Imported Upstream version 4.3.2.1

upstream/latest upstream/4.3.2.1
Oleg Moskalenko 11 years ago
parent 81d53ce44b
commit f076c92e44
  1. 8
      ChangeLog
  2. 87
      INSTALL
  3. 26
      README.turnserver
  4. 4
      STATUS
  5. 8
      TODO
  6. 48
      configure
  7. 9
      examples/etc/turnserver.conf
  8. 2
      man/man1/turnadmin.1
  9. 23
      man/man1/turnserver.1
  10. 2
      man/man1/turnutils.1
  11. 2
      rpm/build.settings.sh
  12. 4
      rpm/turnserver.spec
  13. 41
      src/apps/common/apputils.c
  14. 67
      src/apps/common/apputils.h
  15. 2
      src/apps/common/hiredis_libevent2.c
  16. 82
      src/apps/relay/dtls_listener.c
  17. 189
      src/apps/relay/mainrelay.c
  18. 9
      src/apps/relay/mainrelay.h
  19. 54
      src/apps/relay/netengine.c
  20. 63
      src/apps/relay/ns_ioalib_engine_impl.c
  21. 28
      src/apps/relay/ns_ioalib_impl.h
  22. 11
      src/apps/uclient/mainuclient.c
  23. 13
      src/apps/uclient/startuclient.c
  24. 4
      src/ns_turn_defs.h

@ -1,3 +1,11 @@
12/13/2014 Oleg Moskalenko <mom040267@gmail.com>
Version 4.3.2.1 'Tolomei':
- Redis read message queue bug fixed;
- STUN/TURN ALPN supported (when compiled with OpenSSL 1.0.2+ );
- DTLS v1.2 supported (when compiled with OpenSSL 1.0.2+ );
- Auto optimal ECDH parameters (when compiled with OpenSSL 1.0.2+ );
- TLS/DTLS code cleaning.
11/29/2014 Oleg Moskalenko <mom040267@gmail.com>
Version 4.3.1.3 'Tolomei':
- Reliability fixes (Issue 141 from rfc5766-turn-server).

@ -150,7 +150,49 @@ NOTE: On most modern systems, the build will produce dynamically linked
executables. If you want statically linked executables, you have to modify,
accordingly, the Makefile.in template file.
IV. INSTALL
IV. OPENSSL
If you are using the OpenSSL that is coming with your system, and you are
OK with it, then you do not have to read this chapter. If your system has
an outdated OpenSSL version, or if you need some very fresh OpenSSL features
that are not present in the current usual stable version, then you may have
to compile (and run) your TURN server with a different OpenSSL version.
For example, if you need ALPN feature, or DTLS1.2, and your system comes with
OpenSSL 1.0.1, you will not be able to use those features unless you install
OpenSSL 1.0.2 and compile and run the TURN server with the newer version.
The problem is, it is usually not safe to replace the system's OpenSSL with
a different version. Some systems are "bound" to its "native" OpenSSL
installations, and their behavior may become unpredictable with the newer
versions.
So you want to preserve your system's OpenSSL but you want to compile and to
run the TURN server with newer OpenSSL version. There are different ways to
do that. We are suggesting the following:
1) Download the OpenSSL version from openssl.org.
2) Let's assume that we want to install the "custom" OpenSSL into /opt.
Configure and build OpenSSL as:
$ ./config --prefix=/opt
$ make
$ make install
Those commands will install OpenSSL into /opt, with static libraries (no
dynamic libraries).
3) Build the TURN server:
$ ./configure --prefix=/opt
$ make
Those commands will build the TURN server binaries, statically linked
against the newer OpenSSL.
4) Then you can run the TURN server without setting the dynamic
libraries paths - because it has been linked statically against the newer
OpenSSL libraries.
One potential problem is that libevent2 is using the OpenSSL, too. So, ideally,
to be 100% safe of all potential discrepancies in the runtime, we'd suggesting
rebuilding libevent2 with the newer OpenSSL, too.
V. INSTALL
This step is optional. You can run the turnserver from the original build
directory, successfully, without installing the TURN server into your system.
@ -206,7 +248,7 @@ but if you have some libraries in different non-default directories then
you will have to add them manually to the search path, or you will have
to adjust LD_LIBRARY_PATH.
V. PLATFORMS
VI. PLATFORMS
The TURN Server is using generic *NIX system APIs and is supposed to be
usable on wide range of *NIX systems.
@ -244,7 +286,7 @@ The code is compatible with C++ compiler, and a C++ compiler
$ CC=g++ ./configure
$ make
VII. WHICH EXTRA LIBRARIES AND UTILITIES YOU NEED
VIII. WHICH EXTRA LIBRARIES AND UTILITIES YOU NEED
In addition to common *NIX OS services and libraries, to compile this code,
OpenSSL (version 1.0.0a or better recommended) and libevent2 (version 2.0.5
@ -443,7 +485,7 @@ that will set the installation prefix to /usr (without "--prefix=/usr"
by default it would be installed to /usr/local). This is necessary if you
want to overwrite your existing older OpenSSL installation.
VIII. BUILDING WITH NON-DEFAULT PREFIX DIRECTORY
IX. BUILDING WITH NON-DEFAULT PREFIX DIRECTORY
Say, you have an older system with old openssl and old libevent
library and you do not want to change that, but you still want
@ -482,7 +524,7 @@ by using
$ ldconfig -m <libdirname> (BSD)
$ crle -u -l <libdirname> (Solaris)
IX. TEST SCRIPTS
X. TEST SCRIPTS
First of all, you can use the test vectors from RFC 5769 to double-check that the
STUN/TURN message encoding algorithms work properly. Run the utility:
@ -564,15 +606,16 @@ and the peer.
Check the README.* files and the comments in the scripts relay.sh and
secure_relay.sh as a guidance how to run the TURN server.
X. OS X compilation notes
XI. OS X compilation notes
OS X usually has an older version of openssl supplied, with some Apple
additions. The the "native" openssl will work, within its limitations,
but the best option is to install a good fresh openssl development
library, from http://www.openssl.org. You will have
to handle the dynamic linking of the generated binaries.
to handle the dynamic linking of the generated binaries, or use the
static linking (see the section OPENSSL).
XI. MS Windows and Cygwin support
XII. MS Windows and Cygwin support
Currently, this project cannot be compiled under MS Windows.
@ -585,7 +628,7 @@ libevent2 runtime and libevent-devel packages. "Manual" libevent2 compilation
and installation in Cygwin is not recommended and does not garantee a good
outcome.
XII. CLIENT API LIBRARY.
XIII. CLIENT API LIBRARY.
The compilation process will create lib/ sub-directory with libturnclient.a
library. The header files for this library are located in include/turn/client/
@ -594,7 +637,7 @@ TurnMsgLib.h header. An example of C++ code can be found in stunclient.c file.
This file is compiled as a C++ program if C++ compiler is used, and as a C
program if C compiler is used.
XIII. DOCS
XIV. DOCS
After installation, the man page turnserver(1) must be available. The man page
is located in man/man1 subdirectory. If you want to see the man page without
@ -606,7 +649,7 @@ HTML-formatted client library functions reference is located in docs/html
subdirectory of the original archive tree. After the installation, it will
be placed in PREFIX/share/doc/turnserver/html.
XIV. SQLite setup
XV. SQLite setup
The site http://www.sqlite.org site has excellent extensive documentation.
@ -778,7 +821,7 @@ Fill in users, for example:
$ bin/turnadmin -A -b "/var/db/turndb" -u gorst -p hero
$ bin/turnadmin -A -b "/var/db/turndb" -u ninefingers -p youhavetoberealistic
XV. PostgreSQL setup
XVI. PostgreSQL setup
The site http://www.postgresql.org site has excellent extensive documentation.
For a quick-start guide, you can take a look into this page:
@ -902,7 +945,7 @@ Fill in users, for example:
$ bin/turnadmin -A -e "host=localhost dbname=coturn user=turn password=turn" -u gorst -p hero
$ bin/turnadmin -A -e "host=localhost dbname=coturn user=turn password=turn" -u ninefingers -p youhavetoberealistic
XVI. MySQL (MariaDB) setup
XVII. MySQL (MariaDB) setup
The MySQL setup is similar to PostgreSQL (same idea), and is well documented
on their site http://www.mysql.org. The TURN Server database schema is the
@ -985,7 +1028,7 @@ ca, capath, cert, key, cipher (see
http://dev.mysql.com/doc/refman/5.1/en/ssl-options.html for the
command options description).
XVII. MongoDB setup
XVIII. MongoDB setup
The MongoDB setup is well documented on their site http://docs.mongodb.org/manual/.
@ -1017,7 +1060,7 @@ explanations for the Postgres, for example.
See the file testmongosetup.sh for the database structure examples.
XVIII. Redis setup
XIX. Redis setup
The Redis setup is well documented on their site http://redis.io.
The TURN Server Redis database schema description can be found
@ -1088,20 +1131,20 @@ Redis TURN admin commands:
See the file testredisdbsetup.sh for the data structure examples.
XIX. Performance tuning
XX. Performance tuning
This topic is covered in the wiki page:
http://code.google.com/p/coturn/wiki/turn_performance_and_load_balance
XX. TURN Server setup
XXI. TURN Server setup
Read the project wiki pages: http://code.google.com/p/coturn/w/list
Also, check the project from page links to the TURN/WebRTC configuration examples.
It may give you an idea how it can be done.
XXI. Management interface
XXII. Management interface
You have a telnet interface (enabled by default) to access the turnserver process,
to view its state, to gather some statistical information, and to make some changes
@ -1117,3 +1160,11 @@ or ::1). The CLI may have a password configured, but that password is
transferred over the network unencrypted, too. So sticking to the local system
CLI access, and accessing the turnserver system terminal with ssh only, would
be a wise decision.
XXIII. ALPN support.
Starting with version 4.3.2.1, the TURN server supports the ALPN STUN
specifications (http://tools.ietf.org/html/draft-ietf-tram-alpn-08).
If the ALPN functionality is needed, then OpenSSL version 1.0.2 or
newer has to be used. See OPENSSL section for the OpenSSL upgrade hints.

@ -195,11 +195,11 @@ Flags:
--no-sslv3 Do not allow SSLv3 protocol.
--no-tlsv1 Do not allow TLSv1 protocol.
--no-tlsv1 Do not allow TLSv1/DTLSv1 protocol.
--no-tlsv1_1 Do not allow TLSv1.1 protocol.
--no-tlsv1_2 Do not allow TLSv1.2 protocol.
--no-tlsv1_2 Do not allow TLSv1.2/DTLSv1.2 protocol.
--no-udp Do not start UDP client listeners.
@ -444,8 +444,11 @@ Options with required values:
Forces TURN server to verify the client SSL certificates.
By default, no CA is set and no client certificate check is performed.
--ec-curve-name Curve name for EC ciphers, if supported by OpenSSL library (TLS and DTLS).
The default value is prime256v1.
--ec-curve-name 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.
--dh-file Use custom DH TLS key, stored in PEM format in the file.
Flags --dh566 and --dh2066 are ignored when the DH key is taken from a file.
@ -775,7 +778,18 @@ it will set the users for you (see the turnadmin manuals). If you are using SQLi
turnserver or turnadmin 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).
=================================
ALPN
The server supports ALPNs "stun.turn" and "stun.nat-discovery", when
compiled with OpenSSL 1.0.2 or newer. If the server receives a TLS/DTLS
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 extention field. If no stun.* label is found, then the server
does not include the ALPN information into the ServerHello.
=================================
LIBRARIES
@ -786,7 +800,7 @@ The C++ wrapper for the messaging functionality is located in TurnMsgLib.h heade
An example of C++ code can be found in stunclient.c file.
=================================
DOCS
After installation, run the command:

@ -108,6 +108,10 @@ compatibility.
46) Third-party security mechanism (through oAuth) implemented.
47) SQLite support added as default database.
48) DTLS1.2 supported.
49) ALPN stun.turn and stun.nat-discovery supported.
Things to be implemented in future (the development roadmap)
are described in the TODO file.

@ -47,7 +47,7 @@
==================================================================
Nope
1) EC curve new features in OpenSSL 1.0.2
==================================================================
@ -57,11 +57,7 @@ Nope
1) For extra difficult NAT/FWs, consider implementing Websockets.
2) ALPN with TLS and DTLS (when OpenSSL 1.0.2 is available).
3) Redirect draft.
4) DTLS 1.2 (when available).
2) Redirect draft.
==================================================================

48
configure vendored

@ -7,8 +7,6 @@ cleanup() {
rm -rf ${TMPCPROGB}
rm -rf ${TH_TMPCPROGC}
rm -rf ${TH_TMPCPROGB}
rm -rf ${DTLS_TMPCPROGC}
rm -rf ${DTLS_TMPCPROGB}
rm -rf ${GCM_TMPCPROGC}
rm -rf ${GCM_TMPCPROGB}
rm -rf ${PQ_TMPCPROGC}
@ -239,21 +237,6 @@ pthread_testbarriers() {
fi
}
dtls_testlib() {
if [ -z "${TURN_NO_DTLS}" ] ; then
${CC} ${DTLS_TMPCPROGC} -o ${DTLS_TMPCPROGB} ${OSCFLAGS} ${OSLIBS} 2>>/dev/null
ER=$?
if [ ${ER} -eq 0 ] ; then
return 1
else
return 0
fi
else
return 0
fi
}
gcm_testlib() {
if [ -z "${TURN_NO_GCM}" ] ; then
@ -686,19 +669,6 @@ int main(int argc, char** argv) {
!
DTLS_TMPCPROG=__test__ccomp__dtls__$$
DTLS_TMPCPROGC=${TMPDIR}/${DTLS_TMPCPROG}.c
DTLS_TMPCPROGB=${TMPDIR}/${DTLS_TMPCPROG}
cat > ${DTLS_TMPCPROGC} <<!
#include <stdlib.h>
#include <openssl/ssl.h>
#include <openssl/bio.h>
int main(int argc, char** argv) {
return (((int)(BIO_CTRL_DGRAM_QUERY_MTU)) + argc + (int)(argv[argc][0]) + DTLSv1_listen(NULL,NULL));
}
!
GCM_TMPCPROG=__test__ccomp__gcm__$$
GCM_TMPCPROGC=${TMPDIR}/${GCM_TMPCPROG}.c
GCM_TMPCPROGB=${TMPDIR}/${GCM_TMPCPROG}
@ -961,24 +931,6 @@ else
exit
fi
###########################
# Can we use DTLS ?
###########################
if [ -z ${TURN_NO_DTLS} ] ; then
dtls_testlib
ER=$?
if [ ${ER} -eq 0 ] ; then
${ECHO_CMD} "WARNING: Cannot find DTLS support."
${ECHO_CMD} "Turning DTLS off."
TURN_NO_DTLS="-DTURN_NO_DTLS"
fi
else
TURN_NO_DTLS="-DTURN_NO_DTLS"
fi
###########################
# Can we use GCM cipher ?
###########################

@ -418,8 +418,11 @@
# 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.
#
#ec-curve-name=prime256v1
@ -620,7 +623,7 @@
#
#ne=[1|2|3]
# Do not allow an SSL/TLS version of protocol
# Do not allow an SSL/TLS/DTLS version of protocol
#
#no-sslv2
#no-sslv3

@ -1,5 +1,5 @@
.\" Text automatically generated by txt2man
.TH TURN 1 "06 December 2014" "" ""
.TH TURN 1 "13 December 2014" "" ""
.SH GENERAL INFORMATION
\fIturnadmin\fP is a TURN administration tool. This tool can be used to manage

@ -1,5 +1,5 @@
.\" Text automatically generated by txt2man
.TH TURN 1 "06 December 2014" "" ""
.TH TURN 1 "13 December 2014" "" ""
.SH GENERAL INFORMATION
The \fBTURN Server\fP project contains the source code of a TURN server and TURN client
@ -291,7 +291,7 @@ Do not allow SSLv3 protocol.
.TP
.B
\fB\-\-no\-tlsv1\fP
Do not allow TLSv1 protocol.
Do not allow TLSv1/DTLSv1 protocol.
.TP
.B
\fB\-\-no\-tlsv1_1\fP
@ -299,7 +299,7 @@ Do not allow TLSv1.1 protocol.
.TP
.B
\fB\-\-no\-tlsv1_2\fP
Do not allow TLSv1.2 protocol.
Do not allow TLSv1.2/DTLSv1.2 protocol.
.TP
.B
\fB\-\-no\-udp\fP
@ -649,8 +649,11 @@ By default, no CA is set and no client certificate check is performed.
.TP
.B
\fB\-\-ec\-curve\-name\fP
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.
.TP
.B
\fB\-\-dh\-file\fP
@ -1032,6 +1035,16 @@ TURN server installation process creates an empty initialized SQLite database in
location (/var/db/turndb or /usr/local/var/db/turndb or /var/lib/turn/turndb, depending on the system).
.PP
=================================
.SH ALPN
The server supports ALPNs "stun.turn" and "stun.nat\-discovery", when
compiled with OpenSSL 1.0.2 or newer. If the server receives a TLS/DTLS
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 extention field. If no stun.* label is found, then the server
does not include the ALPN information into the ServerHello.
.PP
=================================
.SH LIBRARIES
In the lib/ sub\-directory the build process will create TURN client messaging library.

@ -1,5 +1,5 @@
.\" Text automatically generated by txt2man
.TH TURN 1 "06 December 2014" "" ""
.TH TURN 1 "13 December 2014" "" ""
.SH GENERAL INFORMATION
A set of turnutils_* programs provides some utility functionality to be used

@ -2,7 +2,7 @@
# Common settings script.
TURNVERSION=4.3.1.3
TURNVERSION=4.3.2.1
BUILDDIR=~/rpmbuild
ARCH=`uname -p`
TURNSERVER_SVN_URL=http://coturn.googlecode.com/svn

@ -1,5 +1,5 @@
Name: turnserver
Version: 4.3.1.3
Version: 4.3.2.1
Release: 0%{dist}
Summary: Coturn TURN Server
@ -294,6 +294,8 @@ fi
%{_includedir}/turn/client/TurnMsgLib.h
%changelog
* Sat Dec 13 2014 Oleg Moskalenko <mom040267@gmail.com>
- Sync to 4.3.2.1
* Sat Nov 29 2014 Oleg Moskalenko <mom040267@gmail.com>
- Sync to 4.3.1.3
* Mon Nov 23 2014 Oleg Moskalenko <mom040267@gmail.com>

@ -349,7 +349,7 @@ int set_socket_df(evutil_socket_t fd, int family, int value)
static int get_mtu_from_ssl(SSL* ssl)
{
int ret = SOSO_MTU;
#if !defined(TURN_NO_DTLS)
#if DTLS_SUPPORTED
if(ssl)
ret = BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
#else
@ -395,7 +395,7 @@ int decrease_mtu(SSL* ssl, int mtu, int verbose)
if (verbose)
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "1. mtu to use: %d\n", mtu);
#if !defined(TURN_NO_DTLS)
#if DTLS_SUPPORTED
SSL_set_mtu(ssl,mtu);
BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_SET_MTU, mtu, NULL);
#endif
@ -416,7 +416,7 @@ int set_mtu_df(SSL* ssl, evutil_socket_t fd, int family, int mtu, int df_value,
set_query_mtu(ssl);
if(verbose) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"3. mtu to use: %d\n",mtu);
#if !defined(TURN_NO_DTLS)
#if DTLS_SUPPORTED
SSL_set_mtu(ssl,mtu);
@ -847,23 +847,31 @@ static const char* turn_get_method(const SSL_METHOD *method, const char* mdefaul
return "TLSv1.0";
} else if(method == TLSv1_client_method()) {
return "TLSv1.0";
#if defined(SSL_TXT_TLSV1_1)
#if TLSv1_1_SUPPORTED
} else if(method == TLSv1_1_server_method()) {
return "TLSv1.1";
} else if(method == TLSv1_1_client_method()) {
return "TLSv1.1";
#if defined(SSL_TXT_TLSV1_2)
#if TLSv1_2_SUPPORTED
} else if(method == TLSv1_2_server_method()) {
return "TLSv1.2";
} else if(method == TLSv1_2_client_method()) {
return "TLSv1.2";
#endif
#endif
#if !defined(TURN_NO_DTLS)
#if DTLS_SUPPORTED
} else if(method == DTLSv1_server_method()) {
return "DTLSv1.0";
return "DTLSv1.0";
} else if(method == DTLSv1_client_method()) {
return "DTLSv1.0";
#if DTLSv1_2_SUPPORTED
} else if(method == DTLSv1_2_server_method()) {
return "DTLSv1.2";
} else if(method == DTLSv1_2_client_method()) {
return "DTLSv1.2";
#endif
#endif
} else {
if(mdefault)
@ -872,20 +880,23 @@ static const char* turn_get_method(const SSL_METHOD *method, const char* mdefaul
}
}
}
}
const char* turn_get_ssl_method(SSL *ssl, const char* mdefault)
{
if(!ssl)
return mdefault;
else {
const char* ret = "unknown";
if(!ssl) {
ret = mdefault;
} else {
const SSL_METHOD *method = SSL_get_ssl_method(ssl);
if(!method)
return mdefault;
else
return turn_get_method(method, mdefault);
if(!method) {
ret = mdefault;
} else {
ret = turn_get_method(method, mdefault);
}
}
return ret;
}
//////////// EVENT BASE ///////////////

@ -53,15 +53,78 @@ extern "C" {
extern int IS_TURN_SERVER;
/* ALPN */
#define OPENSSL_FIRST_ALPN_VERSION (0x10002003L)
#define STUN_ALPN "stun.nat-discovery"
#define TURN_ALPN "stun.turn"
#define HTTP_ALPN "http/1.1"
#if OPENSSL_VERSION_NUMBER >= OPENSSL_FIRST_ALPN_VERSION
#define ALPN_SUPPORTED 1
#else
#define ALPN_SUPPORTED 0
#endif
/* TLS */
#if defined(TURN_NO_TLS)
#define TLS_SUPPORTED 0
#define TLSv1_1_SUPPORTED 0
#define TLSv1_2_SUPPORTED 0
#else
#define TLS_SUPPORTED 1
#if defined(SSL_OP_NO_TLSv1_1)
#define TLSv1_1_SUPPORTED 1
#else
#define TLSv1_1_SUPPORTED 0
#endif
#if defined(SSL_OP_NO_TLSv1_2)
#define TLSv1_2_SUPPORTED 1
#else
#define TLSv1_2_SUPPORTED 0
#endif
#endif
#if defined(TURN_NO_DTLS) || !defined(DTLS_CTRL_LISTEN)
#define DTLS_SUPPORTED 0
#define DTLSv1_2_SUPPORTED 0
#else
#define DTLS_SUPPORTED 1
#if defined(SSL_OP_NO_DTLSv1_2)
#define DTLSv1_2_SUPPORTED 1
#else
#define DTLSv1_2_SUPPORTED 0
#endif
#endif
#if OPENSSL_VERSION_NUMBER >= OPENSSL_FIRST_ALPN_VERSION
#define SSL_SESSION_ECDH_AUTO_SUPPORTED 1
#else
#define SSL_SESSION_ECDH_AUTO_SUPPORTED 0
#endif
/////////// SSL //////////////////////////
enum _TURN_TLS_TYPE {
TURN_TLS_NO=0,
TURN_TLS_SSL23,
TURN_TLS_v1_0,
#if defined(SSL_TXT_TLSV1_1)
#if TLSv1_1_SUPPORTED
TURN_TLS_v1_1,
#if defined(SSL_TXT_TLSV1_2)
#if TLSv1_2_SUPPORTED
TURN_TLS_v1_2,
#endif
#endif

@ -267,7 +267,7 @@ redis_context_handle redisLibeventAttach(struct event_base *base, char *ip0, int
/* Initialize and install read/write events */
e->rev = event_new(e->base,e->context->c.fd,
EV_READ,redisLibeventReadEvent,
EV_READ|EV_PERSIST,redisLibeventReadEvent,
e);
e->wev = event_new(e->base,e->context->c.fd,

@ -58,7 +58,12 @@ struct dtls_listener_relay_server_info {
ioa_engine_handle e;
turn_turnserver *ts;
int verbose;
#if DTLS_SUPPORTED
SSL_CTX *dtls_ctx;
#if DTLSv1_2_SUPPORTED
SSL_CTX *dtls_ctx_v1_2;
#endif
#endif
struct event *udp_listen_ev;
ioa_socket_handle udp_listen_s;
ur_addr_map *children_ss; /* map of socket children on remote addr */
@ -79,27 +84,28 @@ int is_dtls_handshake_message(const unsigned char* buf, int len);
int is_dtls_data_message(const unsigned char* buf, int len);
int is_dtls_alert_message(const unsigned char* buf, int len);
int is_dtls_cipher_change_message(const unsigned char* buf, int len);
int get_dtls_version(const unsigned char* buf, int len);
int is_dtls_message(const unsigned char* buf, int len);
int is_dtls_handshake_message(const unsigned char* buf, int len) {
return (buf && len>3 && buf[0]==0x16 && buf[1]==0xfe && buf[2]==0xff);
return (buf && len>3 && buf[0]==0x16 && buf[1]==0xfe && ((buf[2]==0xff)||(buf[2]==0xfd)));
}
int is_dtls_data_message(const unsigned char* buf, int len) {
return (buf && len>3 && buf[0]==0x17 && buf[1]==0xfe && buf[2]==0xff);
return (buf && len>3 && buf[0]==0x17 && buf[1]==0xfe && ((buf[2]==0xff)||(buf[2]==0xfd)));
}
int is_dtls_alert_message(const unsigned char* buf, int len) {
return (buf && len>3 && buf[0]==0x15 && buf[1]==0xfe && buf[2]==0xff);
return (buf && len>3 && buf[0]==0x15 && buf[1]==0xfe && ((buf[2]==0xff)||(buf[2]==0xfd)));
}
int is_dtls_cipher_change_message(const unsigned char* buf, int len) {
return (buf && len>3 && buf[0]==0x14 && buf[1]==0xfe && buf[2]==0xff);
return (buf && len>3 && buf[0]==0x14 && buf[1]==0xfe && ((buf[2]==0xff)||(buf[2]==0xfd)));
}
int is_dtls_message(const unsigned char* buf, int len) {
if(buf && (len>3) && (buf[1])==0xfe && (buf[2]==0xff)) {
if(buf && (len>3) && (buf[1])==0xfe && ((buf[2]==0xff)||(buf[2]==0xfd))) {
switch (buf[0]) {
case 0x14:
case 0x15:
@ -113,9 +119,16 @@ int is_dtls_message(const unsigned char* buf, int len) {
return 0;
}
/* 0 - 1.0, 1 - 1.2 */
int get_dtls_version(const unsigned char* buf, int len) {
if(buf && (len>3) && (buf[2] == 0xfd))
return 1;
return 0;
}
///////////// utils /////////////////////
#if !defined(TURN_NO_DTLS)
#if DTLS_SUPPORTED
static void calculate_cookie(SSL* ssl, unsigned char *cookie_secret, unsigned int cookie_length) {
long rv=(long)ssl;
@ -266,7 +279,18 @@ static ioa_socket_handle dtls_server_input_handler(dtls_listener_relay_server_ty
timeout.tv_usec = 0;
BIO_ctrl(wbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
connecting_ssl = SSL_NEW(server->dtls_ctx);
#if DTLSv1_2_SUPPORTED
if(get_dtls_version(ioa_network_buffer_data(nbh),
(int)ioa_network_buffer_get_size(nbh)) == 1) {
connecting_ssl = SSL_NEW(server->dtls_ctx_v1_2);
} else {
connecting_ssl = SSL_NEW(server->dtls_ctx);
}
#else
{
connecting_ssl = SSL_NEW(server->dtls_ctx);
}
#endif
SSL_set_accept_state(connecting_ssl);
@ -404,7 +428,7 @@ static int handle_udp_packet(dtls_listener_relay_server_type *server,
chs = NULL;
#if !defined(TURN_NO_DTLS)
#if DTLS_SUPPORTED
if (!turn_params.no_dtls &&
is_dtls_handshake_message(ioa_network_buffer_data(sm->m.sm.nd.nbh),
(int)ioa_network_buffer_get_size(sm->m.sm.nd.nbh))) {
@ -513,7 +537,7 @@ static int create_new_connected_udp_socket(
ret->current_tos = s->current_tos;
ret->default_tos = s->default_tos;
#if !defined(TURN_NO_DTLS)
#if DTLS_SUPPORTED
if (!turn_params.no_dtls
&& is_dtls_handshake_message(
ioa_network_buffer_data(server->sm.m.sm.nd.nbh),
@ -536,7 +560,18 @@ static int create_new_connected_udp_socket(
timeout.tv_usec = 0;
BIO_ctrl(wbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
connecting_ssl = SSL_NEW(server->dtls_ctx);
#if DTLSv1_2_SUPPORTED
if(get_dtls_version(ioa_network_buffer_data(server->sm.m.sm.nd.nbh),
(int)ioa_network_buffer_get_size(server->sm.m.sm.nd.nbh)) == 1) {
connecting_ssl = SSL_NEW(server->dtls_ctx_v1_2);
} else {
connecting_ssl = SSL_NEW(server->dtls_ctx);
}
#else
{
connecting_ssl = SSL_NEW(server->dtls_ctx);
}
#endif
SSL_set_accept_state(connecting_ssl);
@ -566,7 +601,6 @@ static int create_new_connected_udp_socket(
server->sm.m.sm.nd.nbh = NULL;
ret->st = DTLS_SOCKET;
STRCPY(ret->orig_ctx_type,"DTLSv1.0");
}
#endif
@ -864,7 +898,14 @@ static int init_server(dtls_listener_relay_server_type* server,
if(!server) return -1;
#if DTLS_SUPPORTED
server->dtls_ctx = e->dtls_ctx;
#if DTLSv1_2_SUPPORTED
server->dtls_ctx_v1_2 = e->dtls_ctx_v1_2;
#endif
#endif
server->ts = ts;
server->connect_cb = send_socket;
@ -881,6 +922,7 @@ static int init_server(dtls_listener_relay_server_type* server,
server->e = e;
#if DTLS_SUPPORTED
if(server->dtls_ctx) {
#if defined(REQUEST_CLIENT_CERT)
@ -890,12 +932,26 @@ static int init_server(dtls_listener_relay_server_type* server,
SSL_CTX_set_read_ahead(server->dtls_ctx, 1);
#if !defined(TURN_NO_DTLS)
SSL_CTX_set_cookie_generate_cb(server->dtls_ctx, generate_cookie);
SSL_CTX_set_cookie_verify_cb(server->dtls_ctx, verify_cookie);
#endif
}
#if DTLSv1_2_SUPPORTED
if(server->dtls_ctx_v1_2) {
#if defined(REQUEST_CLIENT_CERT)
/* If client has to authenticate, then */
SSL_CTX_set_verify(server->dtls_ctx_v1_2, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, dtls_verify_callback);
#endif
SSL_CTX_set_read_ahead(server->dtls_ctx_v1_2, 1);
SSL_CTX_set_cookie_generate_cb(server->dtls_ctx_v1_2, generate_cookie);
SSL_CTX_set_cookie_verify_cb(server->dtls_ctx_v1_2, verify_cookie);
}
#endif
#endif
return create_server_socket(server, report_creation);
}

@ -65,28 +65,30 @@ static int anon_credentials = 0;
#define DEFAULT_GENERAL_RELAY_SERVERS_NUMBER (1)
turn_params_t turn_params = {
NULL, NULL,
#if defined(SSL_TXT_TLSV1_1)
#if TLSv1_1_SUPPORTED
NULL,
#if defined(SSL_TXT_TLSV1_2)
#if TLSv1_2_SUPPORTED
NULL,
#endif
#endif
#if DTLS_SUPPORTED
NULL,
#endif
#if DTLSv1_2_SUPPORTED
NULL,
#endif
DH_1066, "", DEFAULT_EC_CURVE_NAME, "",
DH_1066, "", "", "",
"turn_server_cert.pem","turn_server_pkey.pem", "", "",
0,0,0,0,0,
#if defined(TURN_NO_TLS)
#if !TLS_SUPPORTED
1,
#else
0,
#endif
#if defined(TURN_NO_DTLS)
#if !DTLS_SUPPORTED
1,
#else
0,
@ -507,17 +509,20 @@ static char Usage[] = "Usage: turnserver [options]\n"
" --CA-file <filename> CA file in OpenSSL format.\n"
" Forces TURN server to verify the client SSL certificates.\n"
" By default, no CA is set and no client certificate check is performed.\n"
" --ec-curve-name <curve-name> Curve name for EC ciphers, if supported by OpenSSL library\n"
" (TLS and DTLS). The default value is prime256v1.\n"
" --ec-curve-name <curve-name> Curve name for EC ciphers, if supported by OpenSSL\n"
" library (TLS and DTLS). The default value is prime256v1,\n"
" if pre-OpenSSL 1.0.2 is used. With OpenSSL 1.0.2+,\n"
" an optimal curve will be automatically calculated, if not defined\n"
" by this option.\n"
" --dh566 Use 566 bits predefined DH TLS key. Default size of the predefined key is 1066.\n"
" --dh2066 Use 2066 bits predefined DH TLS key. Default size of the predefined key is 1066.\n"
" --dh-file <dh-file-name> Use custom DH TLS key, stored in PEM format in the file.\n"
" Flags --dh566 and --dh2066 are ignored when the DH key is taken from a file.\n"
" --no-sslv2 Do not allow SSLv2 protocol.\n"
" --no-sslv3 Do not allow SSLv3 protocol.\n"
" --no-tlsv1 Do not allow TLSv1 protocol.\n"
" --no-tlsv1 Do not allow TLSv1/DTLSv1 protocol.\n"
" --no-tlsv1_1 Do not allow TLSv1.1 protocol.\n"
" --no-tlsv1_2 Do not allow TLSv1.2 protocol.\n"
" --no-tlsv1_2 Do not allow TLSv1.2/DTLSv1.2 protocol.\n"
" --no-udp Do not start UDP client listeners.\n"
" --no-tcp Do not start TCP client listeners.\n"
" --no-tls Do not start TLS client listeners.\n"
@ -1219,14 +1224,14 @@ static void set_option(int c, char *value)
turn_params.no_tcp_relay = get_bool_value(value);
break;
case NO_TLS_OPT:
#if defined(TURN_NO_TLS)
#if !TLS_SUPPORTED
turn_params.no_tls = 1;
#else
turn_params.no_tls = get_bool_value(value);
#endif
break;
case NO_DTLS_OPT:
#if !defined(TURN_NO_DTLS)
#if DTLS_SUPPORTED
turn_params.no_dtls = get_bool_value(value);
#else
turn_params.no_dtls = 1;
@ -1610,13 +1615,13 @@ static void print_features(unsigned long mfn)
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\n\n==== Show him the instruments, Practical Frost: ====\n\n");
#if defined(TURN_NO_TLS)
#if !TLS_SUPPORTED
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS is not supported\n");
#else
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS supported\n");
#endif
#if defined(TURN_NO_DTLS)
#if !DTLS_SUPPORTED
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS is not supported\n");
#else
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS supported\n");
@ -1658,17 +1663,7 @@ static void print_features(unsigned long mfn)
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "MongoDB is not supported\n");
#endif
#if defined(OPENSSL_THREADS)
//TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "OpenSSL multithreading supported\n");
#else
TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "OpenSSL multithreading is not supported (?!)\n");
#endif
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "OpenSSL compile-time version 0x%llx: fresh enough\n",(unsigned long long)OPENSSL_VERSION_NUMBER);
#else
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "OpenSSL compile-time version 0x%llx version: antique\n",(unsigned long long)OPENSSL_VERSION_NUMBER);
#endif
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "OpenSSL compile-time version: %s\n",OPENSSL_VERSION_TEXT);
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Default Net Engine version: %d (%s)\n\n=====================================================\n\n", (int)turn_params.net_engine_version, turn_params.net_engine_version_txt[(int)turn_params.net_engine_version]);
@ -1796,11 +1791,11 @@ int main(int argc, char **argv)
optind = 0;
#if defined(TURN_NO_TLS)
#if !TLS_SUPPORTED
turn_params.no_tls = 1;
#endif
#if defined(TURN_NO_DTLS)
#if !DTLS_SUPPORTED
turn_params.no_dtls = 1;
#endif
@ -2339,8 +2334,59 @@ static int pem_password_func(char *buf, int size, int rwflag, void *password)
return (strlen(buf));
}
#if ALPN_SUPPORTED
static int ServerALPNCallback(SSL *s,
const unsigned char **out,
unsigned char *outlen,
const unsigned char *in,
unsigned int inlen,
void *arg) {
UNUSED_ARG(s);
UNUSED_ARG(arg);
unsigned char sa_len = (unsigned char)strlen(STUN_ALPN);
unsigned char ta_len = (unsigned char)strlen(TURN_ALPN);
unsigned char ha_len = (unsigned char)strlen(HTTP_ALPN);
int found_http = 0;
const unsigned char *ptr = in;
while(ptr < (in+inlen)) {
unsigned char current_len = *ptr;
if(ptr+1+current_len > in+inlen)
break;
if((!turn_params.no_stun) && (current_len == sa_len) && (memcmp(ptr+1,STUN_ALPN,sa_len)==0)) {
*out = ptr+1;
*outlen = sa_len;
return SSL_TLSEXT_ERR_OK;
}
if((!turn_params.stun_only) && (current_len == ta_len) && (memcmp(ptr+1,TURN_ALPN,ta_len)==0)) {
*out = ptr+1;
*outlen = ta_len;
return SSL_TLSEXT_ERR_OK;
}
if((current_len == ha_len) && (memcmp(ptr+1,HTTP_ALPN,ha_len)==0)) {
found_http = 1;
}
ptr += 1 + current_len;
}
if(found_http)
return SSL_TLSEXT_ERR_NOACK;
return SSL_TLSEXT_ERR_NOACK; //???
}
#endif
static void set_ctx(SSL_CTX* ctx, const char *protocol)
{
#if ALPN_SUPPORTED
SSL_CTX_set_alpn_select_cb(ctx, ServerALPNCallback, NULL);
#endif
SSL_CTX_set_default_passwd_cb_userdata(ctx, turn_params.tls_password);
SSL_CTX_set_default_passwd_cb(ctx, pem_password_func);
@ -2391,23 +2437,47 @@ static void set_ctx(SSL_CTX* ctx, const char *protocol)
#if !defined(OPENSSL_NO_EC) && defined(OPENSSL_EC_NAMED_CURVE)
{ //Elliptic curve algorithms:
int nid = NID_X9_62_prime256v1;
int nid = 0;
int set_auto_curve = 0;
if (turn_params.ec_curve_name[0]) {
nid = OBJ_sn2nid(turn_params.ec_curve_name);
if (nid == 0) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"unknown curve name (%s), using NID_X9_62_prime256v1\n",turn_params.ec_curve_name);
nid = NID_X9_62_prime256v1;
}
const char* curve_name = turn_params.ec_curve_name;
if (!(curve_name[0])) {
#if !SSL_SESSION_ECDH_AUTO_SUPPORTED
curve_name = DEFAULT_EC_CURVE_NAME;
#endif
set_auto_curve = 1;
}
EC_KEY *ecdh = EC_KEY_new_by_curve_name(nid);
if (!ecdh) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
if(curve_name[0]) {
{
nid = OBJ_sn2nid(curve_name);
if (nid == 0) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"unknown curve name: %s\n",curve_name);
curve_name = DEFAULT_EC_CURVE_NAME;
nid = OBJ_sn2nid(curve_name);
set_auto_curve = 1;
}
}
{
EC_KEY *ecdh = EC_KEY_new_by_curve_name(nid);
if (!ecdh) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
"%s: ERROR: allocate EC suite\n",__FUNCTION__);
} else {
SSL_CTX_set_tmp_ecdh(ctx, ecdh);
EC_KEY_free(ecdh);
set_auto_curve = 1;
} else {
SSL_CTX_set_tmp_ecdh(ctx, ecdh);
EC_KEY_free(ecdh);
}
}
}
if(set_auto_curve) {
#if SSL_SESSION_ECDH_AUTO_SUPPORTED
SSL_CTX_set_ecdh_auto(ctx,1);
#endif
set_auto_curve = 0;
}
}
#endif
@ -2437,6 +2507,14 @@ static void set_ctx(SSL_CTX* ctx, const char *protocol)
dh = get_dh1066();
}
/*
if(!dh) {
dh = DH_new();
DH_generate_parameters_ex(dh, 32, DH_GENERATOR_2, 0);
DH_generate_key(dh);
}
*/
if(!dh) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: cannot allocate DH suite\n",__FUNCTION__);
} else {
@ -2464,11 +2542,22 @@ static void set_ctx(SSL_CTX* ctx, const char *protocol)
if(turn_params.no_tlsv1_1)
op |= SSL_OP_NO_TLSv1_1;
#endif
#if defined(SSL_OP_NO_TLSv1_2)
if(turn_params.no_tlsv1_2)
op |= SSL_OP_NO_TLSv1_2;
#endif
#if defined(SSL_OP_NO_DTLSv1) && DTLS_SUPPORTED
if(turn_params.no_tlsv1)
op |= SSL_OP_NO_DTLSv1;
#endif
#if defined(SSL_OP_NO_DTLSv1_2) && DTLSv1_2_SUPPORTED
if(turn_params.no_tlsv1_2)
op |= SSL_OP_NO_DTLSv1_2;
#endif
#if defined(SSL_OP_CIPHER_SERVER_PREFERENCE)
op |= SSL_OP_CIPHER_SERVER_PREFERENCE;
#endif
@ -2491,7 +2580,7 @@ static void openssl_setup(void)
SSL_load_error_strings();
OpenSSL_add_ssl_algorithms();
#if defined(TURN_NO_TLS)
#if !TLS_SUPPORTED
if(!turn_params.no_tls) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "WARNING: TLS is not supported\n");
turn_params.no_tls = 1;
@ -2521,12 +2610,12 @@ static void openssl_setup(void)
turn_params.tls_ctx_v1_0 = SSL_CTX_new(TLSv1_server_method());
set_ctx(turn_params.tls_ctx_v1_0,"TLS1.0");
}
#if defined(SSL_TXT_TLSV1_1)
#if TLSv1_1_SUPPORTED
if(!turn_params.no_tlsv1_1) {
turn_params.tls_ctx_v1_1 = SSL_CTX_new(TLSv1_1_server_method());
set_ctx(turn_params.tls_ctx_v1_1,"TLS1.1");
}
#if defined(SSL_TXT_TLSV1_2)
#if TLSv1_2_SUPPORTED
if(!turn_params.no_tlsv1_2) {
turn_params.tls_ctx_v1_2 = SSL_CTX_new(TLSv1_2_server_method());
set_ctx(turn_params.tls_ctx_v1_2,"TLS1.2");
@ -2537,7 +2626,7 @@ static void openssl_setup(void)
}
if(!turn_params.no_dtls) {
#if defined(TURN_NO_DTLS)
#if !DTLS_SUPPORTED
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "ERROR: DTLS is not supported.\n");
#else
if(OPENSSL_VERSION_NUMBER < 0x10000000L) {
@ -2546,7 +2635,15 @@ static void openssl_setup(void)
turn_params.dtls_ctx = SSL_CTX_new(DTLSv1_server_method());
set_ctx(turn_params.dtls_ctx,"DTLS");
SSL_CTX_set_read_ahead(turn_params.dtls_ctx, 1);
#if DTLSv1_2_SUPPORTED
turn_params.dtls_ctx_v1_2 = SSL_CTX_new(DTLSv1_2_server_method());
set_ctx(turn_params.dtls_ctx_v1_2,"DTLS1,2");
SSL_CTX_set_read_ahead(turn_params.dtls_ctx_v1_2, 1);
#endif
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS cipher suite: %s\n",turn_params.cipher_list);
#endif
}
}

@ -180,14 +180,19 @@ typedef struct _turn_params_ {
SSL_CTX *tls_ctx_v1_0;
#if defined(SSL_TXT_TLSV1_1)
#if TLSv1_1_SUPPORTED
SSL_CTX *tls_ctx_v1_1;
#if defined(SSL_TXT_TLSV1_2)
#if TLSv1_2_SUPPORTED
SSL_CTX *tls_ctx_v1_2;
#endif
#endif
#if DTLS_SUPPORTED
SSL_CTX *dtls_ctx;
#if DTLSv1_2_SUPPORTED
SSL_CTX *dtls_ctx_v1_2;
#endif
#endif
DH_KEY_SIZE dh_key_size;

@ -940,14 +940,20 @@ static ioa_engine_handle create_new_listener_engine(void)
,turn_params.redis_statsdb
#endif
);
set_ssl_ctx(e, turn_params.tls_ctx_ssl23, turn_params.tls_ctx_v1_0,
#if defined(SSL_TXT_TLSV1_1)
turn_params.tls_ctx_v1_1,
#if defined(SSL_TXT_TLSV1_2)
turn_params.tls_ctx_v1_2,
set_ssl_ctx(e, turn_params.tls_ctx_ssl23, turn_params.tls_ctx_v1_0
#if TLSv1_1_SUPPORTED
,turn_params.tls_ctx_v1_1
#if TLSv1_2_SUPPORTED
,turn_params.tls_ctx_v1_2
#endif
#endif
turn_params.dtls_ctx);
#if DTLS_SUPPORTED
,turn_params.dtls_ctx
#endif
#if DTLSv1_2_SUPPORTED
,turn_params.dtls_ctx_v1_2
#endif
);
ioa_engine_set_rtcp_map(e, turn_params.listener.rtcpmap);
return e;
}
@ -990,14 +996,20 @@ static void setup_listener(void)
if(!turn_params.listener.ioa_eng)
exit(-1);
set_ssl_ctx(turn_params.listener.ioa_eng, turn_params.tls_ctx_ssl23, turn_params.tls_ctx_v1_0,
#if defined(SSL_TXT_TLSV1_1)
turn_params.tls_ctx_v1_1,
#if defined(SSL_TXT_TLSV1_2)
turn_params.tls_ctx_v1_2,
set_ssl_ctx(turn_params.listener.ioa_eng, turn_params.tls_ctx_ssl23, turn_params.tls_ctx_v1_0
#if TLSv1_1_SUPPORTED
,turn_params.tls_ctx_v1_1
#if TLSv1_2_SUPPORTED
,turn_params.tls_ctx_v1_2
#endif
#endif
#if DTLS_SUPPORTED
,turn_params.dtls_ctx
#endif
#if DTLSv1_2_SUPPORTED
,turn_params.dtls_ctx_v1_2
#endif
turn_params.dtls_ctx);
);
turn_params.listener.rtcpmap = rtcp_map_create(turn_params.listener.ioa_eng);
@ -1558,14 +1570,20 @@ static void setup_relay_server(struct relay_server *rs, ioa_engine_handle e, int
,turn_params.redis_statsdb
#endif
);
set_ssl_ctx(rs->ioa_eng, turn_params.tls_ctx_ssl23, turn_params.tls_ctx_v1_0,
#if defined(SSL_TXT_TLSV1_1)
turn_params.tls_ctx_v1_1,
#if defined(SSL_TXT_TLSV1_2)
turn_params.tls_ctx_v1_2,
set_ssl_ctx(rs->ioa_eng, turn_params.tls_ctx_ssl23, turn_params.tls_ctx_v1_0
#if TLSv1_1_SUPPORTED
,turn_params.tls_ctx_v1_1
#if TLSv1_2_SUPPORTED
,turn_params.tls_ctx_v1_2
#endif
#endif
#if DTLS_SUPPORTED
,turn_params.dtls_ctx
#endif
turn_params.dtls_ctx);
#if DTLSv1_2_SUPPORTED
,turn_params.dtls_ctx_v1_2
#endif
);
ioa_engine_set_rtcp_map(rs->ioa_eng, turn_params.listener.rtcpmap);
}

@ -38,7 +38,7 @@
#include "ns_ioalib_impl.h"
#if !defined(TURN_NO_TLS)
#if TLS_SUPPORTED
#include <event2/bufferevent_ssl.h>
#endif
@ -433,24 +433,35 @@ ioa_engine_handle create_ioa_engine(super_memory_t *sm,
void set_ssl_ctx(ioa_engine_handle e,
SSL_CTX *tls_ctx_ssl23,
SSL_CTX *tls_ctx_v1_0,
#if defined(SSL_TXT_TLSV1_1)
SSL_CTX *tls_ctx_v1_1,
#if defined(SSL_TXT_TLSV1_2)
SSL_CTX *tls_ctx_v1_2,
SSL_CTX *tls_ctx_v1_0
#if TLSv1_1_SUPPORTED
,SSL_CTX *tls_ctx_v1_1
#if TLSv1_2_SUPPORTED
,SSL_CTX *tls_ctx_v1_2
#endif
#endif
SSL_CTX *dtls_ctx)
#if DTLS_SUPPORTED
,SSL_CTX *dtls_ctx
#endif
#if DTLSv1_2_SUPPORTED
,SSL_CTX *dtls_ctx_v1_2
#endif
)
{
e->tls_ctx_ssl23 = tls_ctx_ssl23;
e->tls_ctx_v1_0 = tls_ctx_v1_0;
#if defined(SSL_TXT_TLSV1_1)
#if TLSv1_1_SUPPORTED
e->tls_ctx_v1_1 = tls_ctx_v1_1;
#if defined(SSL_TXT_TLSV1_2)
#if TLSv1_2_SUPPORTED
e->tls_ctx_v1_2 = tls_ctx_v1_2;
#endif
#endif
#if DTLS_SUPPORTED
e->dtls_ctx = dtls_ctx;
#endif
#if DTLSv1_2_SUPPORTED
e->dtls_ctx_v1_2 = dtls_ctx_v1_2;
#endif
}
void ioa_engine_set_rtcp_map(ioa_engine_handle e, rtcp_map *rtcpmap)
@ -1554,8 +1565,6 @@ ioa_socket_handle create_ioa_socket_from_ssl(ioa_engine_handle e, ioa_socket_han
if(ret) {
set_socket_ssl(ret,ssl);
if(st == DTLS_SOCKET)
STRCPY(ret->orig_ctx_type,"DTLSv1.0");
}
return ret;
@ -1754,8 +1763,6 @@ ioa_socket_handle detach_ioa_socket(ioa_socket_handle s)
addr_cpy(&(ret->local_addr),&(s->local_addr));
ret->connected = s->connected;
addr_cpy(&(ret->remote_addr),&(s->remote_addr));
STRCPY(ret->orig_ctx_type, s->orig_ctx_type);
delete_socket_from_map(s);
delete_socket_from_parent(s);
@ -2239,7 +2246,8 @@ int udp_recvfrom(evutil_socket_t fd, ioa_addr* orig_addr, const ioa_addr *like_a
return len;
}
#if !defined(TURN_NO_TLS)
#if TLS_SUPPORTED
static TURN_TLS_TYPE check_tentative_tls(ioa_socket_raw fd)
{
TURN_TLS_TYPE ret = TURN_TLS_NO;
@ -2318,7 +2326,7 @@ static int socket_input_worker(ioa_socket_handle s)
}
if(s->st == TLS_SOCKET) {
#if !defined(TURN_NO_TLS)
#if TLS_SUPPORTED
SSL *ctx = bufferevent_openssl_get_ssl(s->bev);
if(!ctx || SSL_get_shutdown(ctx)) {
s->tobeclosed = 1;
@ -2337,7 +2345,7 @@ static int socket_input_worker(ioa_socket_handle s)
if(s->st == TENTATIVE_TCP_SOCKET) {
EVENT_DEL(s->read_event);
#if !defined(TURN_NO_TLS)
#if TLS_SUPPORTED
TURN_TLS_TYPE tls_type = check_tentative_tls(s->fd);
if(tls_type) {
s->st = TLS_SOCKET;
@ -2348,32 +2356,28 @@ static int socket_input_worker(ioa_socket_handle s)
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!!%s on socket: 0x%lx, st=%d, sat=%d: bev already exist\n", __FUNCTION__,(long)s, s->st, s->sat);
}
switch(tls_type) {
#if defined(SSL_TXT_TLSV1_2)
#if TLSv1_2_SUPPORTED
case TURN_TLS_v1_2:
if(s->e->tls_ctx_v1_2) {
set_socket_ssl(s,SSL_NEW(s->e->tls_ctx_v1_2));
STRCPY(s->orig_ctx_type,"TLSv1.2");
}
break;
#endif
#if defined(SSL_TXT_TLSV1_1)
#if TLSv1_1_SUPPORTED
case TURN_TLS_v1_1:
if(s->e->tls_ctx_v1_1) {
set_socket_ssl(s,SSL_NEW(s->e->tls_ctx_v1_1));
STRCPY(s->orig_ctx_type,"TLSv1.1");
}
break;
#endif
case TURN_TLS_v1_0:
if(s->e->tls_ctx_v1_0) {
set_socket_ssl(s,SSL_NEW(s->e->tls_ctx_v1_0));
STRCPY(s->orig_ctx_type,"TLSv1.0");
}
break;
default:
if(s->e->tls_ctx_ssl23) {
set_socket_ssl(s,SSL_NEW(s->e->tls_ctx_ssl23));
STRCPY(s->orig_ctx_type,"SSLv23");
} else {
s->tobeclosed = 1;
return 0;
@ -2392,7 +2396,7 @@ static int socket_input_worker(ioa_socket_handle s)
bufferevent_enable(s->bev, EV_READ|EV_WRITE); /* Start reading. */
}
} else
#endif //TURN_NO_TLS
#endif //TLS_SUPPORTED
{
s->st = TCP_SOCKET;
if(s->bev) {
@ -2444,7 +2448,7 @@ static int socket_input_worker(ioa_socket_handle s)
s->broken = 1;
log_socket_event(s, "socket read failed, to be closed",1);
} else if(s->st == TLS_SOCKET) {
#if !defined(TURN_NO_TLS)
#if TLS_SUPPORTED
SSL *ctx = bufferevent_openssl_get_ssl(s->bev);
if(!ctx || SSL_get_shutdown(ctx)) {
ret = -1;
@ -3084,7 +3088,7 @@ int send_data_from_ioa_socket_nbh(ioa_socket_handle s, ioa_addr* dest_addr,
if (s->connected && s->bev) {
if (s->st == TLS_SOCKET) {
#if !defined(TURN_NO_TLS)
#if TLS_SUPPORTED
SSL *ctx = bufferevent_openssl_get_ssl(s->bev);
if (!ctx || SSL_get_shutdown(ctx)) {
s->tobeclosed = 1;
@ -3241,11 +3245,10 @@ int register_callback_on_ioa_socket(ioa_engine_handle e, ioa_socket_handle s, in
return -1;
}
} else {
#if !defined(TURN_NO_TLS)
#if TLS_SUPPORTED
if(!(s->ssl)) {
//??? how we can get to this point ???
set_socket_ssl(s,SSL_NEW(e->tls_ctx_ssl23));
STRCPY(s->orig_ctx_type,"SSLv23");
s->bev = bufferevent_openssl_socket_new(s->e->event_base,
s->fd,
s->ssl,
@ -3460,7 +3463,7 @@ const char* get_ioa_socket_cipher(ioa_socket_handle s)
const char* get_ioa_socket_ssl_method(ioa_socket_handle s)
{
if(s && s->ssl) {
return turn_get_ssl_method(s->ssl, s->orig_ctx_type);
return turn_get_ssl_method(s->ssl, "UNKNOWN");
}
return "no SSL";
}
@ -3478,8 +3481,8 @@ void turn_report_allocation_set(void *a, turn_time_t lifetime, int refresh)
ioa_engine_handle e = turn_server_get_engine(server);
if(e && e->verbose && ss->client_socket) {
if(ss->client_socket->ssl) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"session %018llu: %s, realm=<%s>, username=<%s>, lifetime=%lu, cipher=%s, method=%s (%s)\n", (unsigned long long)ss->id, status, (char*)ss->realm_options.name, (char*)ss->username, (unsigned long)lifetime, SSL_get_cipher(ss->client_socket->ssl),
turn_get_ssl_method(ss->client_socket->ssl, ss->client_socket->orig_ctx_type),ss->client_socket->orig_ctx_type);
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"session %018llu: %s, realm=<%s>, username=<%s>, lifetime=%lu, cipher=%s, method=%s\n", (unsigned long long)ss->id, status, (char*)ss->realm_options.name, (char*)ss->username, (unsigned long)lifetime, SSL_get_cipher(ss->client_socket->ssl),
turn_get_ssl_method(ss->client_socket->ssl, "UNKNOWN"));
} else {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"session %018llu: %s, realm=<%s>, username=<%s>, lifetime=%lu\n", (unsigned long long)ss->id, status, (char*)ss->realm_options.name, (char*)ss->username, (unsigned long)lifetime);
}

@ -143,13 +143,18 @@ struct _ioa_engine
stun_buffer_list bufs;
SSL_CTX *tls_ctx_ssl23;
SSL_CTX *tls_ctx_v1_0;
#if defined(SSL_TXT_TLSV1_1)
#if TLSv1_1_SUPPORTED
SSL_CTX *tls_ctx_v1_1;
#if defined(SSL_TXT_TLSV1_2)
#if TLSv1_2_SUPPORTED
SSL_CTX *tls_ctx_v1_2;
#endif
#endif
#if DTLS_SUPPORTED
SSL_CTX *dtls_ctx;
#endif
#if DTLSv1_2_SUPPORTED
SSL_CTX *dtls_ctx_v1_2;
#endif
turn_time_t jiffie; /* bandwidth check interval */
ioa_timer_handle timer_ev;
s08bits cmsg[TURN_CMSG_SZ+1];
@ -180,7 +185,6 @@ struct _ioa_socket
SSL* ssl;
u32bits ssl_renegs;
int in_write;
char orig_ctx_type[16];
int bound;
int local_addr_known;
ioa_addr local_addr;
@ -251,14 +255,20 @@ ioa_engine_handle create_ioa_engine(super_memory_t *sm,
void set_ssl_ctx(ioa_engine_handle e,
SSL_CTX *tls_ctx_ssl23,
SSL_CTX *tls_ctx_v1_0,
#if defined(SSL_TXT_TLSV1_1)
SSL_CTX *tls_ctx_v1_1,
#if defined(SSL_TXT_TLSV1_2)
SSL_CTX *tls_ctx_v1_2,
SSL_CTX *tls_ctx_v1_0
#if TLSv1_1_SUPPORTED
,SSL_CTX *tls_ctx_v1_1
#if TLSv1_2_SUPPORTED
,SSL_CTX *tls_ctx_v1_2
#endif
#endif
#if DTLS_SUPPORTED
,SSL_CTX *dtls_ctx
#endif
#if DTLSv1_2_SUPPORTED
,SSL_CTX *dtls_ctx_v1_2
#endif
SSL_CTX *dtls_ctx);
);
void ioa_engine_set_rtcp_map(ioa_engine_handle e, rtcp_map *rtcpmap);

@ -517,18 +517,18 @@ int main(int argc, char **argv)
root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(TLSv1_client_method());
SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite);
root_tls_ctx_num++;
#if defined(SSL_TXT_TLSV1_1)
#if TLSv1_1_SUPPORTED
root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(TLSv1_1_client_method());
SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite);
root_tls_ctx_num++;
#if defined(SSL_TXT_TLSV1_2)
#if TLSv1_2_SUPPORTED
root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(TLSv1_2_client_method());
SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite);
root_tls_ctx_num++;
#endif
#endif
} else {
#if defined(TURN_NO_DTLS)
#if !DTLS_SUPPORTED
fprintf(stderr,"ERROR: DTLS is not supported.\n");
exit(-1);
#else
@ -538,6 +538,11 @@ int main(int argc, char **argv)
root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(DTLSv1_client_method());
SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite);
root_tls_ctx_num++;
#if DTLSv1_2_SUPPORTED
root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(DTLSv1_2_client_method());
SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite);
root_tls_ctx_num++;
#endif
#endif
}

@ -50,6 +50,11 @@ static uint64_t current_reservation_token = 0;
static int allocate_rtcp = 0;
static const int never_allocate_rtcp = 0;
#if ALPN_SUPPORTED
static const unsigned char kALPNProtos[] = "\x08http/1.1\x09stun.turn\x12stun.nat-discovery";
static const size_t kALPNProtosLen = sizeof(kALPNProtos) - 1;
#endif
/////////////////////////////////////////
int rare_event(void)
@ -79,15 +84,21 @@ static int get_allocate_address_family(ioa_addr *relay_addr) {
static SSL* tls_connect(ioa_socket_raw fd, ioa_addr *remote_addr, int *try_again, int connect_cycle)
{
int ctxtype = (int)(((unsigned long)random())%root_tls_ctx_num);
SSL *ssl;
ssl = SSL_NEW(root_tls_ctx[ctxtype]);
#if ALPN_SUPPORTED
SSL_set_alpn_protos(ssl, kALPNProtos, kALPNProtosLen);
#endif
if(use_tcp) {
SSL_set_fd(ssl, fd);
} else {
#if defined(TURN_NO_DTLS)
#if !DTLS_SUPPORTED
UNUSED_ARG(remote_addr);
fprintf(stderr,"ERROR: DTLS is not supported.\n");
exit(-1);

@ -31,7 +31,7 @@
#ifndef __IOADEFS__
#define __IOADEFS__
#define TURN_SERVER_VERSION "4.3.1.3"
#define TURN_SERVER_VERSION "4.3.2.1"
#define TURN_SERVER_VERSION_NAME "Tolomei"
#define TURN_SOFTWARE "Coturn-" TURN_SERVER_VERSION " '" TURN_SERVER_VERSION_NAME "'"
@ -60,8 +60,6 @@
extern "C" {
#endif
///////////////////////////////////////////
/* NS types: */
#define s08bits char

Loading…
Cancel
Save