initial code import

This commit is contained in:
mom040267 2014-04-20 21:10:18 +00:00
commit 702b29bc22
147 changed files with 47950 additions and 0 deletions

46
AUTHORS Normal file
View File

@ -0,0 +1,46 @@
Oleg Moskalenko <mom040267@gmail.com> :
General design and implementation
(2011-2013);
Gabor Kovesdan, http://kovesdan.org :
FreeBSD packaging
(since v1.5.2.6);
Daniel Pocock, http://danielpocock.com :
Debian packaging
(since v1.8.3.6);
John Selbie (jselbie@gmail.com) :
Stuntman interoperability, RFC5780 fixes
MS Windows port work
(since v1.8.3.6);
Lee Sylvester <lee@designrealm.co.uk> :
Status and statistics - ideas and pilot implementation
(since v1.8.4.0);
Erik Johnston <erikj@openmarket.com> :
Access Control Lists, 2013
(since v1.8.5.0);
Roman Lisagor <roman@demonware.net> :
Testing, code optimization
(since v1.8.6.0);
Vladimir Tsanev <tsachev@gmail.com> :
configure script and Makefile fixes,
Arch Linux port
(since v1.8.6.1);
Po-sheng Lin <personlin118@gmail.com> :
Libevent dependencies cleaning
(since v2.0.1.1);
Peter Dunkley <peter.dunkley@crocodilertc.net> :
CentOS/Fedora port
(since v2.6.6.1)
Mutsutoshi Yoshimoto <mutsutoshi.yoshimoto@mixi.co.jp>
TCP routing: testing and bug fixes
(since v3.2.2.7)

970
ChangeLog Normal file
View File

@ -0,0 +1,970 @@
04/20/2014 Oleg Moskalenko <mom040267@gmail.com>
Version 3.3.0.0 'Threetrees':
- multi-tenant server.
04/13/2014 Oleg Moskalenko <mom040267@gmail.com>
Version 3.2.3.6 'Marshal West':
- Addresses logging fixed.
- Redis admin options fixed.
- Redis compilation cleaned.
04/07/2014 Oleg Moskalenko <mom040267@gmail.com>
Version 3.2.3.5 'Marshal West':
- Mobile allocation quota fixed (issue 121);
- --simple-log option added (Issue 122);
- documentation fixes (REST API, Redis).
04/06/2014 Oleg Moskalenko <mom040267@gmail.com>
Version 3.2.3.4 'Marshal West':
- Mobile TCP sessions fixed (issue 120);
- log information improvements.
04/04/2014 Oleg Moskalenko <mom040267@gmail.com>
Version 3.2.3.3 'Marshal West':
- Pkey and cert file descriptors to be closed
on initialization (issue 118);
- Address bind indefinite cycle on start-up fixed
(Issue 119);
- Allocation counters time lag improved.
03/30/2014 Oleg Moskalenko <mom040267@gmail.com>
Version 3.2.3.2 'Marshal West':
- Allocation counters fixed (issue 117);
- a possible core dump in the server code fixed;
- a possible memory leak in server fixed.
03/29/2014 Oleg Moskalenko <mom040267@gmail.com>
Version 3.2.3.1 'Marshal West':
- TCP congestion avoidance completed.
- Read and write streams are treated separately in
bandwidth control.
- Test client fixed.
- Experimental SHA256 key storage supported.
03/17/2014 Oleg Moskalenko <mom040267@gmail.com>
Version 3.2.2.912 'Marshal West':
- TCP-in-TCP congestion avoidance implemented.
- UDP-in-TCP congestion avoidance improved.
- Alternate-server code cleaned.
03/10/2014 Oleg Moskalenko <mom040267@gmail.com>
Version 3.2.2.911 'Marshal West':
- "Congestion control" for UDP-inside-TCP tunneling;
- memory management improvements;
- socket logging improvements;
- debug info added to CentOS and Fedora RPMs;
- TCP traffic buffering improved;
- Thread barriers cleaned;
- TCP memory leak fixed;
- minor TCP test client improvement.
03/09/2014 Oleg Moskalenko <mom040267@gmail.com>
Version 3.2.2.910 'Marshal West':
- Log messages extended and cleaned.
- Some memory cleaning.
03/02/2014 Oleg Moskalenko <mom040267@gmail.com>
Version 3.2.2.9 'Marshal West':
- Issue 113 fixed (TCP rate limit fixed);
- Issue 114 fixed (TCP stability).
02/18/2014 Oleg Moskalenko <mom040267@gmail.com>
Version 3.2.2.8 'Marshal West':
- Issue 102: SO_BSDCOMPAT socket option removed;
- Issue 104: check for the REALM attribute value;
- Issue 105: no-cli segfault fixed;
- Issue 106: MESSAGE-INTEGRITY removed from DATA indication;
- Issue 108: Server should return 438 on unknown nonce;
- Issue 109: make the random functions stronger (mostly for
transaction ID and for nonce);
- Issue 111: fix valgrind warning on memory initialization.
- Issue 112: RTCP sockets logging.
02/12/2014 Oleg Moskalenko <mom040267@gmail.com>
Version 3.2.2.7 'Marshal West':
- Possible indefinite cycle fixed in TCP/TCP routing (Issue 99);
- Address 0.0.0.0 can be used as a listener address (Issue 100);
- DHCP-configured servers supported (Issue 101);
02/04/2014 Oleg Moskalenko <mom040267@gmail.com>
Version 3.2.2.6 'Marshal West':
- Channel traffic memory copy elimination.
- Send indication memory copy elimination.
- DTLS traffic processing memory copy eliminated.
- Mobility forbidden error code number fixed - according to the new draft document.
- getsockname() usage minimized.
- port allocation improved.
- default relay behavior fixed (when no relay addresses defined).
- atomic create permission request handling (Issue 97).
01/25/2014 Oleg Moskalenko <mom040267@gmail.com>
Version 3.2.2.5 'Marshal West':
- code optimization.
01/24/2014 Oleg Moskalenko <mom040267@gmail.com>
Version 3.2.2.4 'Marshal West':
- HMAC key handling fixed (Issue 96).
01/23/2014 Oleg Moskalenko <mom040267@gmail.com>
Version 3.2.2.3 'Marshal West':
- Security fix (issue 95).
- Default "implicit" relay IP allocation policy is more usable
(issue 94 fixed).
- SSLv2 fixed (for those who are still using it)
(issue 93 fixed).
- Cosmetic changes.
01/19/2014 Oleg Moskalenko <mom040267@gmail.com>
Version 3.2.2.1 'Marshal West':
- CPU/memory cache optimization (memory locality).
- torture tests enhanced.
- stability fixes.
- minor possible memory leak fix.
- new TLS options: --no-sslv2, --no-sslv3, --no-tlsv1,
--no-tlsv1_1, --no-tlsv1_2
01/06/2014 Oleg Moskalenko <mom040267@gmail.com>
Version 3.2.1.4 'Marshal West':
- Linux epoll performance improvements.
- DTLS minor fix.
01/06/2014 Oleg Moskalenko <mom040267@gmail.com>
Version 3.2.1.3 'Marshal West':
- Telnet client added to installation when necessary.
01/05/2014 Oleg Moskalenko <mom040267@gmail.com>
Version 3.2.1.2 'Marshal West':
- Config file adjusted for DragonFly.
01/03/2014 Oleg Moskalenko <mom040267@gmail.com>
Version 3.2.1.1 'Marshal West':
- Minor TLS fix.
- Default cipher list is DEFAULT now.
12/26/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 3.2.1.0 'Marshal West':
- Optimized TCP network engine for Linux 3.9+.
- Security fix: DH and ECDH temporary keys are now
regenerated for each TLS or DTLS session.
- Fix for systems with multiple CPU cores (more than 128).
- DH TLS key now can be configured as 566, 1066 (default) or 2066 bits.
- DH TLS key can be taken from a PEM file.
- Issue 91 (test client crash) fixed.
- Configurable net engine type.
12/25/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 3.1.6.0 'Arch Lector':
- Timers optimization: linked list timers structure
for often-used intervals.
12/23/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 3.1.5.3 'Arch Lector':
- HTTP "keep-alive" support improved.
- TCP channel "fortification".
12/19/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 3.1.5.1 'Arch Lector':
- Private key password allowed for encrypted keys.
- HTTP "keep-alive" supported.
- "psd" CLI command added (ps dump to file).
12/18/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 3.1.4.2 'Arch Lector':
- Time functions optimization.
- Online changes to the alternate servers list thru telnet CLI.
- Certificate chain files allowed.
12/13/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 3.1.3.1 'Arch Lector':
- "Start time" ps command info added.
- Protocol option added to "pu" command.
- "Delete allocation" debug message fixed.
- "Allocation id" debug info message fixed.
- RFC6062 usage statistics fixed.
- Info/Debug messages cleaned.
12/11/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 3.1.2.3 'Arch Lector':
- CentOS 6 package fixed.
12/10/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 3.1.2.2 'Arch Lector':
- ps output typo fixed (TLS params).
- configurable EC curve name.
- CLI TLS-related information extended.
- "print users" (pu) CLI command added.
12/09/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 3.1.2.1 'Arch Lector':
- DH cipher suites basic implementation.
- Elliptic Curve cipher suites basic implementation.
- RFC 6062 crash fixed.
- More CLI parameters added.
- Redis allocation statistics fixed.
- Number of cli max session lines configurable.
- uclient cipher suite configurable.
12/08/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 3.1.1.0 'Arch Lector':
- Telnet CLI.
- RFC 6062 internal messaging fixed.
- Server relay endpoints (a non-standard feature).
- "atomic line" stdout log print.
- printed help minor fix.
- client program does not necessary
require certificate for TLS.
- docs fixes.
- allocation quota bug fixed.
11/29/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 3.0.2.1 'Practical Frost':
- TCP stability fixes.
- RFC 6062 "first packet(s)" bug fixed.
- RFC 6062 stability fixes.
- Multithreaded Mobile ICE.
11/28/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 3.0.1.4 'Practical Frost':
- CentOS/Fedora packaging fixed.
- PID file fixed.
11/26/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 3.0.1.3 'Practical Frost':
- Misc cosmetic changes.
- CentOS/Fedora packaging fixed.
11/25/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 3.0.1.2 'Practical Frost':
- Mobility draft implemented.
- DTLS communications fixes.
- UDP Linux optimization.
- Log output time starts with 0.
- A new "drop root privileges" options:
--proc-user and --proc-group added.
- SHA256 agility updated: 426 error code on too weak SHA function.
- "-m 0" and "-m 1" options improved.
- non-threading environment support dropped.
- stability fixes.
- OpenSUSE support added.
11/10/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 3.0.0.0 'Practical Frost':
- New network engine for Linux kernel 3.9+.
11/08/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 2.6.7.2 'Harding Grim':
- SHA256 agility updated: 441 error code on too weak SHA function.
11/07/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 2.6.7.1 'Harding Grim':
- CentOS / Fedora uninstall script.
- Debian compilation error fixed.
- OpenSSL 0.9.7 and earlier build fixed.
- NetBSD build fixed.
11/03/2013 Oleg Moskalenko <mom040267@gmail.com>,
Peter Dunkley <peter.dunkley@crocodilertc.net>
Version 2.6.7.0 'Harding Grim':
- CentOS 6 pre-compiled distribution.
- Fedora pre-compiled distribution.
- TURN_NO_TLS case compilation cleaning.
- Text files cleaning.
- Issue 68 fixed (no-stun option added).
10/27/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 2.6.6.1 'Harding Grim':
- SHA256 added as a non-standard message integrity option.
- CentOS rpm specs added.
- Peter Dunkley added to the authors list.
10/20/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 2.6.6.0 'Harding Grim':
- Cygwin loopback relay interfaces fixed (Issue 62).
- rpath added to the Makefile (Issue 63).
- CONFLICTS added to FreeBSD port Makefile (Issue 64).
- Certificate check options, for server and for the test client (Issue 65).
- Some compilation cleaning.
10/09/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 2.6.5.2 'Harding Grim':
- Documentation changes.
- Redis-related memory leak fixed (Issue 61).
09/25/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 2.6.4.1 'Harding Grim':
- Crash on uninitialized redis db name is fixed (Issue 59).
- Optional authentication of STUN Binding request is implemented (Issue 60).
09/16/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 2.6.3.1 'Harding Grim':
- Issue 58: support changing white/black IP lists while server is running.
database tables (keys for redis) added for that new functionality.
09/03/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 2.6.2.2 'Harding Grim':
- Issue 52: RFC 6062 relay endpoints connection process
fixed for Linux pre-3.9 kernel.
09/03/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 2.6.2.1 'Harding Grim':
- UDP performance improvements.
- Issue 56: DTLS scaleability improvements.
- Issue 55: DTLS support in Cygwin.
- Issue 57: --pidfile option
- Issue 52: RFC 6062 relay endpoints connection process fixed.
- Issue 53: Fingerprints added to the indications.
- Issue 54: Long-term credentials mechanism integrity and software attributes
added to the indications.
08/11/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 2.6.1.4 'Harding Grim':
- UDP memory leak fixed.
08/11/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 2.6.1.3 'Harding Grim':
- DTLS crash fix.
08/10/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 2.6.1.2 'Harding Grim':
- TLS buffer decreased to avoid memory problems.
- TLS BIO object fix.
- UDP socket open/reopen process fixed.
08/08/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 2.6.1.1 'Harding Grim':
- Network optimization:
* "pure" UDP setup optimized (when no DTLS configured);
* Auxiliary listening endpoints (configured by
--aux-server=<ip:port>).
* --udp-self-balance option to balance the UDP traffic
among the aux endpoints (for clients supporting
300 ALTERNATE-SERVER response).
- Security improvements:
* no authentication required on the load balancer server (Issue 50).
* REST API improvement:
= --secret-ts-exp-time option deprecated;
= In REST API timestamp, we are now using
the expiration time (Issue 31).
* Configurable cipher suite in the TURN server.
* SSL3 support.
* TLS 1.1 and 1.2 support.
* SSL2 "encapsulation" mode support.
* NULL OpenSSL cipher is allowed to be negotiated between
server and client.
* -U option (NULL cipher) added to the test client.
* DTLS crash fixed on overload.
- STUN enhancements and fixes:
* Classic STUN transaction ID fixed (Issue 48).
* Classic STUN attribute ERROR fixed (Issue 49).
* Unused RFC 5780 functionality removed from TCP, TLS and DTLS relays.
* resources optimization for stun-only: short connection expiration time.
07/26/2013 Oleg Moskalenko <mom040267@gmail.com>,
Vladimir Tsanev <tsachev@gmail.com>
Version 2.5.2.1 'Shivers':
- log file placement changes.
- Base64 encode/decode memory initialization fix.
07/23/2013 Oleg Moskalenko <mom040267@gmail.com>,
Po-sheng Lin <personlin118@gmail.com>
Version 2.5.1.2 'Shivers':
- getopt fix in client test programs.
- cosmetic changes.
- allow anonymous alternate-server functionality.
07/21/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 2.5.1.1 'Shivers':
- Improved "split" network engine:
two different threading models for TCP and UDP.
- DTLS crash fixed.
- Multithreading with Cygwin.
07/20/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 2.1.3.1 'Shivers':
- DTLS improvements for DOS attacks
- deeper optimization for DOS attack (mostly for Linux)
07/19/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 2.1.2.0 'Shivers':
- deeper optimization for DOS attack (mostly for Linux)
07/18/2013 Oleg Moskalenko <mom040267@gmail.com>,
Po-sheng Lin <personlin118@gmail.com>
Version 2.1.1.1 'Shivers':
- udp fixes.
- Makefile cleaning.
- Dependencies cleaning.
- DOS attack client emulation.
- DOS attack defense logic added to the server.
07/14/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 2.0.0.0 'Shivers':
- new networking engine:
- scalable UDP socket model.
- multithreaded TCP relay implemented.
- race condition fixed in authentication of TCP sessions.
- Cygwin "port" fixed.
06/23/2013 Oleg Moskalenko <mom040267@gmail.com>,
Vladimir Tsanev <tsachev@gmail.com>
Version 1.8.7.0 'Black Dow':
- Added support for obsolete "classic" STUN RFC 3489;
- Full TURN support for Cygwin implemented: MS-Win UDP sockets fixed;
- Relay threads number changed;
- Fedora warnings fixed;
- turndb/testdbsetup.sh example file added;
- Multiple Makefile and ./configure script fixes implemented:
* Changes taken from Arch Linux port;
* Manpages installation and deinstallation;
* rfc5769check utility removed from installation, it is used for the
compilation result test only and makes no sense for the end user;
* "--parameter" format support in ./configure script; it allows
simpler native OS package definitions (like in Debian package);
* Mac OS X linking warnings removed.
* pthread test fixed.
06/08/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.6.3 'Black Dow':
- DONT-FRAGMENT flag removed on UDP listening (clients-facing) sockets.
- UDP fix for Cygwin only: UDP channels work fine now.
- docs fixes.
06/06/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.6.2 'Black Dow':
- Just cosmetic re-packaging for Debian, tarball warnings removed.
06/05/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.6.1 'Black Dow':
- Peer permissions bug fixed.
06/03/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.6.0 'Black Dow':
- Optimization.
- Mac OS X compilation fixes.
06/01/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.5.4 'Black Dow':
- Issues 29 and 30 fixed (channels padding).
- minor fixes.
- Mac OS X compilation fixes.
- Cygwin-related compilation fixes and INSTALL additions.
05/31/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.5.3 'Black Dow':
- REST API extra script example and docs extention.
05/26/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.5.1 'Black Dow':
- Config file parsing fixed (Issue 28)
05/20/2013 Oleg Moskalenko <mom040267@gmail.com>,
Erik Johnston <erikj@openmarket.com>
Version 1.8.5.0 'Black Dow':
- IP access control lists.
- log file name fix.
- alt-* ports default behavior changed.
- "passive TCP" option in uclient.
05/18/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.4.5 'Black Dow':
- socket conditions cleaned (SIGPIPE, etc)
05/17/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.4.4 'Black Dow':
- configuration and installation adjusted for:
- NetBSD;
- Solaris;
- OpenBSD;
- Screen messages fixed;
- code security fixes.
05/15/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.4.3 'Black Dow':
- Compilation warning removed.
- Log file fixed (Issue 26)
05/15/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.4.2 'Black Dow':
- repackaging for Debian compliance. Docs separated.
05/14/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.4.1 'Black Dow':
- Cosmetics (docs, warnings, etc).
- More complex case of TURN-server-behind-NAT is implemented,
when multiple public-ip/private-ip mappings are involved.
05/13/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.4.0 'Black Dow':
- Redis DB support added.
- Crash on help text fixed.
- Max allocation time can be changed in the command-line or
in the config file.
05/09/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.3.9 'Black Dow':
- No changes - just the tarball is repackaged for Debian compatibility.
05/07/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.3.8 'Black Dow':
- multicast and loopback addresses disallow options added.
- option to direct all log messages to the system log (syslog).
05/02/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.3.7 'Black Dow':
- Allocation status log.
05/01/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.3.6 'Black Dow':
- Stuntman client interoperability fixed.
- Manpages installation fixed.
04/30/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.3.5 'Black Dow':
- Lintian fixes.
04/27/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.3.4 'Black Dow':
- Installation fixes.
04/26/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.3.3 'Black Dow':
- Log file midnight rollover implemented (Issue 15).
04/25/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.3.1 'Black Dow':
- Configurable REST API separator symbol (Issue 16).
- Stale Nonce bug fixed (Issue 17).
- Minor client fix.
04/21/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.3.0 'Black Dow':
- STUN stand-alone functionality improved according to RFC 5389.
- ALTERNATE-SERVER implemented as "light" load balancing feature.
- stun-only option implemented.
- scripts directory reorganized.
04/19/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.2.1 'Black Dow':
- Misc docs fixes.
04/13/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.2.0 'Black Dow':
- Multiple database shared secrets supported for REST API.
- Added support for some OpenSSL FIPS versions (like openssl 0.9.8e-fips-rhel5).
04/13/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.1.3 'Black Dow':
- Maintenance (docs, etc).
- Added partial support for Cygwin. Only TCP & TLS protocols
are support for client-to-server communications (as in RFC 5766 and
RFC 6062). UDP supported only for relay communications. DTLS is not
supported at all. The problem is in Winsock UDP sockets implementation.
04/11/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.1.2 'Black Dow':
- Work on configuration and build.
04/9/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.1.1 'Black Dow':
- Docs improvements.
- Load balancing use case added to TurnNetworks.pdf.
- Verbose mode split into 'normal' and 'extra' modes.
- Logging extended and fixed.
04/7/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.1.0 'Black Dow':
- Compilation flags improved.
- utility programs renamed and moved to bin/ directory.
- README and turnserver man page separated into three sections -
turnserver, turnadmin, turnutils.
04/6/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.0.6 'Black Dow':
- Added option "--psql-userdb" for better visual separation
between PostgreSQL and MySQL stuff.
- turnadmin flat files handling fixed.
- added set/show commands to turnadmin for secret key.
04/6/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.0.5 'Black Dow':
- turnadmin MySQL connection fixed.
- minor cosmetic changes.
- Added "list" commands for long-term and short-term users,
to turnadmin.
04/5/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.0.4 'Black Dow':
- Minor compilation fixes.
- Minor docs fixes.
- "connect_timeout" option support for MySQL.
04/5/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.0.3 'Black Dow':
- Issue 11 (secret timestamp check) fixed.
04/4/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.0.2 'Black Dow':
- TCP sockets flush removed.
- rfc5769check utility removed from the Makefile.
04/4/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.0.1 'Black Dow':
- Some short-term auth problems fixed.
- rfc5769check utility added to the Makefile and upgraded.
04/3/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.8.0.0 'Black Dow':
- Short-term credentials mechanism implemented.
04/2/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.7.3.1 'Superior Glokta':
- Listeners code cleaned.
- The default number of extra relay threads changes from 0 to 1.
04/1/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.7.3.0 'Superior Glokta':
- Issue 10 fixed: log file control options.
Two options added: --no-stdout-log and --log-file.
03/29/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.7.2.0 'Superior Glokta':
- Issue 9 fixed (uclient).
- Secret-based authentication implemented (see TURNServerRESTAPI.pdf).
- Uclient docs fixed.
- database schema extended (table for the secret added).
03/27/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.7.1.2 'Superior Glokta':
- CHANNEL BIND request handling fixed: now it produces an error
when client is trying to tie the same peer address to
different channels.
- uclient and peer test apps upgraded so that RTP channels
are talking to <port> and RTCP channels are talking
to <port+1> in client-to-peer communication patterns.
- compilation warning is fixed when MySQL is not used.
03/27/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.7.1.1 'Superior Glokta':
- CONNECT response fixed in RFC 6062.
- uclient checks server responses integrity.
03/26/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.7.1.0 'Superior Glokta':
- MySQL support added for the user keys repository.
- PostgreSQL support improved.
- Docs fixed.
- 64 bits platform fixes.
03/23/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.7.0.0 'Glokta':
- Authentication fix.
- PostgreSQL database can be used as the user keys repository.
03/21/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.6.1.3 'Whirrun':
- UDP segmentation fault fixed
03/21/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.6.1.2 'Whirrun':
- RFC 6062 fix
03/21/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.6.1.1 'Whirrun':
- Authentication error fixed
03/19/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.6.1.0 'Whirrun':
- --stale-nonce option
- working on userdb
- "hang on" option fixed in uclient
03/18/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.6.0.2 'Whirrun':
- working on userdb
- c++ compilation fix
03/17/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.6.0.1 'Whirrun':
- uclient performance improved
- TurnNetworks.pdf document added
03/15/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.6.0.0 'Whirrun':
- "Pure" TCP relaying (RFC 6062) implemented.
- Network interactions fixes.
- RFC 6062 test scripts added.
03/03/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.5.2.8 'Iosiv Lestek':
- authorization processing improvements.
- peer application fixed.
- some ICE attributes added.
02/27/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.5.2.7 'Iosiv Lestek':
- authorization processing improvements
- Issue 4 fixed.
- secure client-to-client script added
02/22/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.5.2.6 'Iosiv Lestek':
- strcpy/strncpy fixed
- some screen messages fixed
- uclient statistics fixed
- software attribute fixed
- example scripts fixed
02/16/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.5.2.5 'Lestek':
- uclient application fixed
- Docs fixes
02/14/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.5.2.4 'Lestek':
- Crash fixed on unconfigured interfaces
- Docs fixes
02/12/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.5.2.3 'Lestek':
- Added feature: TURN Server always uses fingerprints in a session if
the session client is using fingerprints.
- Default unsecure alternative port changed to 3479,
default secure alternative port changed to 5350.
- TURN Server always trying to search for default certificate file
turn_server_cert.pem and for default private key file
turn_server_pkey.pem, if not certificate or private key is
explicitly configured.
- configurable packet rate in the uclient test program.
- default peer port changed to 3480.
- -z, --no-auth option added to turnserver.
02/11/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.5.2.2 'Lestek':
- Some cleanup added to the network input handlers.
02/9/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.5.2.1 'Lestek':
- Binding requests do not require authentication.
- SOFTWARE in the end of the message.
02/8/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.5.2.0 'Lestek':
- NAT discovery fixed (RFC5780).
02/8/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.5.1.6 'Calder':
- Installation instructions fixed.
02/8/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.5.1.5 'Calder':
- Mac compilation fixes.
- Fixes for old Linuxes.
02/7/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.5.1.4 'Calder':
- Configuration alert (warning) messages.
- Relay addresses by default use listener addresses.
- Realm/user sequence fixed in the config file reading.
01/27/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.5.1.3 'Calder':
- 'External' IP implemented for TURN-server-behind-NAT situation.
01/26/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.5.1.2 'Calder':
- Alternative ports moved to 20000-ish territory.
- Docs fixes.
01/22/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.5.1.1 'Calder':
- Docs fixes.
01/22/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.5.1.0 'Calder':
- C++ compatible headers and build.
- C++ library header.
- HTML-formatted development reference.
01/14/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.5.0.0 'Calder':
- RFC 5769 check utility implemented.
- RFC 5780 STUN extension implemented.
01/13/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.4.2.5 'Scale':
- Issue 2 fixed.
01/08/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.4.2.4 'Scale':
- Bogus "Bind to device" error message removed (Linux).
- Docs improvements.
01/08/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.4.2.3 'Scale':
- Bandwidth limitation implemented (--max-bps option).
- DTLS communications improved.
01/07/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.4.2.2 'Scale':
- Output messages fixed.
- Peer test application accepts multiple listening addresses.
- config search directories improved.
01/06/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.4.2.1 'Scale':
- Examples directory structure fixed
- Installation fixes
- Output messages fixed
01/05/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.4.2 'Scale':
- Daemon execution improved
- Installation fixes
- Added comments to the scripts
01/04/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.4.1.2 'Scale':
- Configure script introduced
- Installation fixes
- Run as daemon
01/01/2013 Oleg Moskalenko <mom040267@gmail.com>
Version 1.4.1 'Scale':
- Options fixes
- Build fixes
- Script fixes
- Installation fixes
12/31/2012 Oleg Moskalenko <mom040267@gmail.com>
Version 1.4 'Scale':
- Separate file for the dynamic user database
- Build fixes
- Script fixes
- Logging fixes
12/29/2012 Oleg Moskalenko <mom040267@gmail.com>
Version 1.3.0.2 'Ferro':
- Debian 'squeeze' compilation fix
12/26/2012 Oleg Moskalenko <mom040267@gmail.com>
Version 1.3.0.1 'Ferro':
- install procedure minor improvements
12/24/2012 Oleg Moskalenko <mom040267@gmail.com>
Version 1.3 'Ferro':
- default conf file renamed to turnserver.conf
- build script improved
- client library linking fixed
- install procedure
12/23/2012 Oleg Moskalenko <mom040267@gmail.com>
Version 1.2.3 'Luthar':
- turnserver options fixed
- man page renamed to turnserver
12/22/2012 Oleg Moskalenko <mom040267@gmail.com>
Version 1.2.2:
- Man page fix
12/21/2012 Oleg Moskalenko <mom040267@gmail.com>
Version 1.2.1 'Juvens':
- Man page
12/21/2012 Oleg Moskalenko <mom040267@gmail.com>
Version 1.2 'Euz':
- Project cleaning
12/20/2012 Oleg Moskalenko <mom040267@gmail.com>
Version 1.1 'no name':
- DTLS extension
12/17/2012 Oleg Moskalenko <mom040267@gmail.com>
Version 1.0 'no name':
- RFC 5766
- RFC 6156

963
INSTALL Normal file
View File

@ -0,0 +1,963 @@
I. TURN Server as a standard OS package
At the present time, several operation systems have this project pre-packaged:
1) FreeBSD (and PC-BSD) have this project as a "port", named "turnserver",
in /usr/ports/net/turnserver directory. Installation is very simple:
# optional commands, to update the ports tree:
$ sudo portsnap fetch
$ sudo portsnap update
# Build and install the TURN Server:
$ cd /usr/ports/net/turnserver
$ sudo make install clean
2) Debian "jessie" (and the recent version of Ubuntu and Mint)
have the predecessor of this project packaged as "rfc5766-turn-server", see the link:
http://packages.qa.debian.org/r/rfc5766-turn-server.html
In the new Debian "jessie", and in the related Ubuntu and Mint, you will
be able to just select rfc5766-turn-server from the packages list and
install it through Synaptic or through the package manager.
3) ArchLinux has alse the predecessor of the TURN server package:
https://aur.archlinux.org/packages/rfc5766-turn-server/
4) OpenSUSE has a package, too:
https://build.opensuse.org/package/show/home:ehauenstein/rfc5766-turn-server
If you are using a pre-packaged TURN server then you can skip
to the section IX.
II. DOWNLOAD
You have to download the archive file turnserver-*.tar.gz and unpack it:
$ tar xfz turnserver-*.tgz
it will create the directory 'turnserver-*' with all sources, build files,
examples and documentation.
III. BUILD
If you are sure that you system is ready for the build (see the section
"Extra libraries and Utilities" below) then you can build the system.
First, you have to run the configure script:
$ cd turnserver-*
$ ./configure
It will create a Makefile customized for your system.
By default, the generated Makefile will be set to install everything
in:
- /usr on Solaris.
- /usr/pkg on NetBSD.
- /usr/local everywhere else.
The binaries will be copied in bin subdirectory of the installation
destination, config files copied to etc subdirectory. There will be
also documents, examples and some other files, in separate directories.
You can change the root configured destination directory by
setting PREFIX variable in the
configure command line. For example:
$ PREFIX=/opt ./configure
Or:
$ ./configure --prefix=/opt
You can change the auxiliary configured destination sub-directories by
setting BINDIR, CONFDIR, MANPREFIX, EXAMPLESDIR, DOCSDIR, LIBDIR, SCHEMADIR
and TURNINCLUDEDIR variables in the
configure command line. For example:
$ PREFIX=/opt BINDIR=/opt/bin64 CONFDIR=/opt/conf ./configure
Or:
$ ./configure --prefix=/opt --bindir=/opt/bin64 --confdir=/opt/conf
You also can change the compilation and link options by
setting common build variables in the
configure command line. For example:
$ CC=clang CFLAGS=-D_CAURIB LDFLAGS=-lshanka ./configure --prefix=/opt/shy
See below a separate INSTALL section for more details.
The script configure is a proprietary script. It will create a Makefile
that you can use to build the project:
$ make
The make command without options will do the following:
- compile the code.
- create bin/ sub-directory and put the TURN server, TURN admin and
"utility" programs there.
- create lib/ sub-directory and put the client library there.
- create include/turn/ sub-directory and put include files there.
The programs can be either called directly, or a shell scripts can be used.
The script examples are located in examples/scripts directory. These scripts
are just examples: you can run them successfully for the tests, but
you will have to change the script parameters for your real environment.
The command:
$ sudo make install
will install everything into the system file structure (see below).
(NOTE: On NetBSD, use "su root -c").
The command:
$ sudo make deinstall
will remove all installed TURN Server files from your system.
The command:
$ make clean
will clean all results of the build and configuration actions.
Do not run "make clean" before "make deinstall". The "clean" command will
remove the Makefile and you will not be able to "deinstall" then. If that
has happened, then run ./configure and make again, then deinstall and then
clean.
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
This step is optional. You can run the turnserver from the original build
directory, successfully, without installing the TURN server into the system.
You have to install the turnserver only if you want to integrate the
turnserver in your system.
Run the command:
$ make install
It will install turnserver in /usr/local/ directory (or to whatever directory
was set in the PREFIX variable). You will have to copy
/usr/local/etc/turnserver.conf.default to /usr/local/etc/turnserver.conf file
and adjust your runtime configuration.
This command will also:
- copy the content of examples subdirectory into
PREFIX/share/examples/turnserver/ directory;
- copy the content of include/turn subdirectory into
PREFIX/include/turn/ directory;
- copy the database schema file turndb/schema.sql into
PREFIX/share/turnserver/
directory;
- copy all docs into PREFIX/share/doc/turnserver/ directory.
The installation destination of "make install" can be changed by
using DESTDIR variable, for example:
$ ./configure --prefix=/usr
$ make
$ make DESTDIR=/opt install
In this example, the root installation directory will be /opt/usr.
The "configure" script by default generates a Makefile with "rpath" option
set for the binaries linking (if your compiler allows that option). If that
is not desirable (like in some OS packaging procedures), then run the
"configure" script with --disable-rpath option.
If you do not want to use the rpath linking option, or you OS or compiler
do not allows that, then after the installation, you may have to adjust the
system-wide shared library search path by using "ldconfig -n <libdirname>"
(Linux), "ldconfig -m <libdirname>" (BSD) or "crle -u -l <libdirname>"
(Solaris). Your system must be able to find the libevent2, openssl and
(optionally) PostgreSQL and/or MySQL (MariaDB) and/or Redis shared libraries,
either with the help of the system-wide library search configuration or by
using LD_LIBRARY_PATH. "make install" will make a non-garantied effort to add
automatically PREFIX/lib and /usr/local/lib to the libraries search path,
but if you have some libraries in different non-default directories
you will have to add them manually to the search path, or you
will have to adjust LD_LIBRARY_PATH.
V. PLATFORMS
The TURN Server is using generic *NIX system APIs and is supposed to be
usable on wide range of *NIX systems.
The following platforms have been used in the development:
- Linux Ubuntu 11.x and 12.x, i386 and x86_64
- FreeBSD 6.x, i386
- FreeBSD 8.x, i386
- PC-BSD 9.x, x86_64
- Solaris 11, x86_64
- Linux CentOS / Red Hat Enterprise Edition 6.3, x86_64 (amd64)
- Linux CentOS / Red Hat Enterprise Edition 6.4, x86_32 (i386)
- Linux Debian 'Squeeze', i386
- Linux Mint 14.1 'Nadia', i386
- Linux Debian 'Wheezy', x86_64
- Cygwin 1.7.20
- NetBSD 6.0.1
- OpenBSD 5.3
- Amazon Linux
- Mac OS X Mountain Lion
- ArchLinux
- Fedora 19
- OpenSUSE 12.3 x86_64
It must work on many other *NIXes, as well. The configure script and/or
Makefile may need adjustments for other *NIXes not mentioned above.
The code of the client messaging library can be compiled and used on
Windows, too, but it is not supported for now.
VI. COMPILERS
The TURN Server is written in C programming language, for portability
and for the performance reasons.
The tested C compilers are:
- gcc 3.4.4 thru 4.8.1
- clang 3.0 or better
- Solaris Studio 12.3 C compiler, version 5.12
It may be compiled with others compilers, too.
The code is compatible with C++ compiler, and a C++ compiler
(like g++) can be used for the compilation, too:
$ CC=g++ ./configure
$ make
VII. 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
or better) are required, the PostgreSQL C client development setup is
optional, the MySQL (MariaDB) C client development setup is optional, and the
Hiredis development files for Redis database access are optional.
For fully functional build, the extra set of libraries must be installed
in full version (the development headers and the libraries to link with).
For runtime, only runtime setup is required. If the build is modified for
static linking, then even runtime installation is not needed.
OpenSSL, libevent2, PostgreSQL, MySQL (or MariaDB) and Hiredis
libraries can be downloaded from their web sites:
- http://www.openssl.org (required);
- http://www.libevent.org (required);
- http://www.postgresql.org (optional);
- http://www.mysql.org (or http://mariadb.org) (optional);
- http://redis.io (optional).
The installations are pretty straightforward - the usual
"./configure" and "make install" commands. Install them into their default
locations - the configure script and the Makefile are assuming that they are
installed in their default locations. If not, then you will have to modify
those.
Most modern popular systems (FreeBSD / PC-BSD, Linux Ubuntu 11.10+, Debian Wheezy,
Linux Mint 14+, Amazon Linux, Fedora) have a simpler way of the third party tools
installation:
*) PC-BSD or FreeBSD (the FRESH ports database is assumed to be installed, with
the turnserver port included):
$ cd /usr/ports/net/turnserver
$ sudo make install clear
That's it - that command will install the TURN server with all necesary
thrid-party tools.
If you system have no fresh ports repository:
$ cd /usr/ports/security/openssl/
$ sudo make install clean
$ cd /usr/ports/devel/libevent2/
$ sudo make install clean
$ cd /usr/ports/databases/postgresql84-client/ (or any other version)
$ sudo make install clean
$ cd /usr/ports/databases/mysql51-client/ (or any other version)
$ sudo make install clean
$ cd /usr/ports/databases/hiredis/
$ sudo make install clean
**) Linux Ubuntu 11.10+, Debian Wheezy, Mint 14+:
$ sudo apt-get install libssl-dev
$ sudo apt-get install libevent-dev
$ sudo apt-get install libpq-dev
$ sudo apt-get install mysql-client
$ sudo apt-get install libmysqlclient-dev
$ sudo apt-get install libhiredis-dev
or you can use Synaptic or other software center.
***) Fedora:
$ sudo yum install openssl-devel
$ sudo yum install libevent
$ sudo yum install libevent-devel
$ sudo yum install postgresql-devel
$ sudo yum install postgresql-server
$ sudo yum install mysql-devel
$ sudo yum install mysql-server
$ sudo yum install hiredis
$ sudo yum install hiredis-devel
****) Amazon Linux is similar to Fedora, but:
- you have to install gcc first:
$ sudo yum install gcc
- hiredis packages are not available, so do not issue the
hiredis installation commands. Redis support will not be
compiled, unless you install it "manually" before the TURN
server compilation. For Amazon EC2 AMIs, we install the
redis manually in the system. But the TURN server can be
perfectly installed without redis support - if you do not
need it.
*****) Some OSes in Debian family (Debian Squeeze and
pre-11.10 Ubuntus) setups are similar to Debian Wheezy,
although some packages have different names.
******) On some CentOS / RedHat 6.x systems you have to install
libevent2 "manually", and optionally you have to download and
install Hiredis, but everything else can be found in the software
repository. Also, if you would like to make an RPM for CentOS,
check the directory rpm/ with the instructions.
NOTE: If your tools are installed in non-standard locations, you will
have to adjust CFLAGS and LDFLAGS environment variables for TURN
server ./configure script. For example, to configure the TURN server
with Solaris 11 PostgreSQL 32-bits setup, you may use a command
like this:
$ CFLAGS="${CFLAGS} -I/usr/postgres/9.2-pgdg/include/" LDFLAGS="${LDFLAGS} -L/usr/postgres/9.2-pgdg/lib/" ./configure
Dynamic library paths:
You may also have to adjust the turn server start script, add PostgreSQL
and/or MySQL and/or Redis runtime library path to LD_LIBRARY_PATH.
Or you may find that it would be more convenient to adjust the
system-wide shared library search path by using commands:
on Linux:
$ ldconfig -n <libdirname>
or on BSD:
$ ldconfig -m <libdirname>
or on Solaris:
$ crle -u -l <libdirname>
On Mac OS X, you have three different choices for dynamic libraries handling:
1) Use DYLD_LIBRARY_PATH environment variable in runtime; OR
2) Before the compilation, check the dynamic libraries and adjust their identification names,
if necessary, to the absolute library path or to @rpath/<library-file-name>.
For exmple, the MySQL dynamic library may need that adjustment. You will have to use
"adjust_name_tool" with -id option for that; OR
3) After the compilation, you can use the same tool, "adjust_name_tool", with option -change,
to adjust the library paths values in the binary, where necessary. All library paths must be
absolute paths or @rpath/... .
See also the next section.
NOTE: See "PostgreSQL setup" and "MySQL setup" and "Redis setup" sections
below for more database setup information.
NOTE: If you do not install PostgreSQL or MySQL or Redis then you will
be limited to flat files for user database. It will work great for
smaller user databases (like 100 users) but for larger systems you
will need PostgreSQL or MySQL or Redis.
NOTE: To run PostgreSQL or MySQL or Redis server on the same system,
you will also have to install a corresponding PostgreSQL or MySQL or
Redis server package. The DB C development packages only provide
development libraries, and client libraries only provide client
access utilities and runtime libraries. The server packages may
include everything - client, C development and server runtime.
NOTE: OpenSSL to be installed before libevent2. When libevent2 is building,
it is checking whether OpenSSL has been already installed, and which version
of OpenSSL. If the OpenSSL is missed, or too old, then libevent_openssl
library is not being created during the build, and you will not be able to
compile the TURN Server with TLS support.
NOTE: An older libevent version, version 1.x.x, is often included in some *NIX
distributions. That version has its deficiencies and is inferior to the newer
libevent2, especially in the performance department. This is why we are
not providing backward compatibility with the older libevent 1.x version.
If you have a system with older libevent, then you have to install the new
libevent2 from their web site. It was tested with older *NIXes
(like FreeBSD 6.x) and it works just fine.
NOTE: For extra security features (DTLS and SHA256) support, OpenSSL version
1.0.0a or newer is recommended. Older versions do not support DTLS, reliably,
in some cases. For example, the Debian 'Squeeze' Linux supplies 0.9.8 version
of OpenSSL, that does not work correctly with DTLS over IPv6. If your system
already has an older version of OpenSSL installed (usually in directory /usr)
then you may want to install your newer OpenSSL "over" the old one (because it
will most probably will not allow removal of the old one). When installing
the newer OpenSSL, run the OpenSSL's configure command like this:
$ ./config --prefix=/usr
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
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
to build the turnserver.
Do the following steps:
1) Download new openssl from openssl.org.
2) Configure and build new openssl and install it into /opt:
$ ./config --prefix=/opt
$ make
$ make install
3) Download the latest libevent2 from libevent.org, configure and install
it into /opt:
$ ./configure --prefix=/opt
$ make
$ make install
4) Change directory to coturn and build it:
$ ./configure --prefix=/opt
$ make
After that, you can either use it locally, or install it into /opt.
But remember that to run it, you have to adjust your LD_LIBRARY_PATH,
like that:
$ LD_LIBRARY_PATH=/opt/lib ./bin/turnserver
An alternative would be adjusting the system-wide shared library search path
by using
$ ldconfig -n <libdirname> (Linux)
$ ldconfig -m <libdirname> (BSD)
$ crle -u -l <libdirname> (Solaris)
IX. TEST SCRIPT SETS
First of all, we can use test vectors from RFC 5769 to double-check that our
STUN/TURN message encoding algorithms work properly. Run the utility:
$ cd examples
$ ./scripts/rfc5769.sh
It will perform several protocol checks and print the results on the output.
If anything has compiled wrongly (TURN Server, or OpenSSL libraries)
then you will see some errors.
Now, you can perform the TURN functionality test (bare minimum TURN example).
If everything compiled properly, then the following programs must run
together successfully, simulating TURN network routing in local loopback
networking environment:
Open two shell screens or consoles:
In shell number 1, run TURN server application:
$ cd examples
$ ./scripts/basic/relay.sh
In shell number 2, run test client application:
$ cd examples
$ ./scripts/basic/udp_c2c_client.sh
If the client application produces output and in approximately 22 seconds
prints the jitter, loss and round-trip-delay statistics, then everything is
fine.
There is another more complex test:
In shell number 1, run TURN server application:
$ cd examples
$ ./scripts/basic/relay.sh
In shell number 2, run "peer" application:
$ cd examples
$ ./scripts/peer.sh
In shell number 3, run test client application:
$ cd examples
$ ./scripts/basic/udp_client.sh (or ./scripts/basic/tcp_client.sh)
There is a similar set of examples/scripts/longtermsecure/* scripts for
TURN environment with long-term authentication mechanism. This set of
scripts is more complex, and checking the scripts options is useful for
understanding how the TURN Server works:
In shell number 1, run secure TURN server application:
$ cd examples
$ ./scripts/longtermsecure/secure_relay.sh
In shell number 2, run "peer" application:
$ cd examples
$ ./scripts/peer.sh
In shell number 3, run secure test client application:
$ cd examples
$ ./scripts/longtermsecure/secure_udp_client.sh
(or ./scripts/longtermsecure/secure_tcp_client.sh)
(or ./scripts/longtermsecure/secure_tls_client.sh)
(or ./scripts/longtermsecure/secure_dtls_client.sh)
(or ./scripts/longtermsecure/secure_udp_c2c.sh for "peerless"
client-to-client communications)
The provided scripts are set for the local loopback communications,
as an example and as a test environment. Real networking IPs must be
used in real work environments.
Try wireshark to check the communications between client, turnserver
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
OS X usually has an older version of openssl supplied, with some Apple
additions. The best option is to install a good fresh openssl development
library, free of Apple tweaks, from http://www.openssl.org. But the "native"
openssl will work, too.
XI. MS Windows and Cygwin support
Currently, this project cannot be compiled under MS Windows.
As the project is using fairly straightforward *NIX API, it is supported
under Cygwin environment in MS Windows.
One note for Cygwin users: we recommended libevent2 installation from the cygwin
"ports" site: http://sourceware.org/cygwinports/ . You will have to install
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.
The compilation process will create lib/ sub-directory with libturnclient.a
library. The header files for this library are located in include/turn/client/
sub-directory. 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.
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
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
installation, run the command:
$ man -M man turnserver
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. 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:
http://www.freebsddiary.org/postgresql.php. That page is written for
FreeBSD users, but it has lots of generic information applicable to other
*NIXes, too.
For the psql-userdb TURN server parameter, you can either set a PostgreSQL
connection string, or a PostgreSQL URI, see the link:
For 8.4 PostgreSQL version:
http://www.postgresql.org/docs/8.4/static/libpq-connect.html
For newer 9.x versions:
http://www.postgresql.org/docs/9.2/static/libpq-connect.html#LIBPQ-CONNSTRING.
In the PostgreSQL connection string or URI, you can set the host, the
access port, the database name, the user, and the user password
(if the access is secured). Numerous other parameters can be set,
see the links above. The TURN server will blindly use that connection
string without any modifications. You are responsible for the right
connection string format.
Below are the steps to setup the PostgreSQL database server from scratch:
1) Install PostgreSQL server.
2) Find and edit Postgres' pg_hba.conf file to set the access options
(see docs). On different systems, it may be located in different places.
Set the lines for local access as "trust" for now (you can change it later),
for TCP/IP access set the value as "md5".
To set TCP/IP access from any host, use "0.0.0.0/0" for IPv4, and "::/0"
for IPv6.
3) Edit postgresql.conf file to allow TCP/IP access - uncomment and edit
the "listen_addresses" option (see docs). On different systems, this file
may be located in different places.
4) Restart your system or restart the postgresql server, for example:
$ sudo /etc/init.d/postgresql stop
$ sudo /etc/init.d/postgresql start
5) Check /etc/passwd file to find out which user account is used for the
PostgreSQL admin access on your system (it may be "pgsql", or "postgres",
or "postgresql"). Let's assume that this is "postgres" account.
6) Create a database for the TURN purposes, with name, say, "turn":
$ createdb -U postgres turn
7) Create a user for the TURN with name, say, "turn":
$ psql -U postgres turn
turn=# create user turn with password 'turn';
turn=#
Ctrl-D
8) Create the TURN users database schema.
The database schema for the TURN server is very minimalistic and is located
in project's turndb/schema.sql file, or in the system's
PREFIX/share/turnserver/schema.sql file after the turnserver installation:
$ cat turndb/schema.sql | psql -U turn turn
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "turnusers_lt_pkey" for table "turnusers_lt"
CREATE TABLE
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "turnusers_st_pkey" for table "turnusers_st"
CREATE TABLE
CREATE TABLE
$
The schema description:
# Table for long-term credentials mechanism authorization:
#
CREATE TABLE turnusers_lt (
realm varchar(512),
name varchar(512),
hmackey char(128),
PRIMARY KEY (realm,name)
);
# Table for short-term credentials mechanism authorisation:
#
CREATE TABLE turnusers_st (
name varchar(512) PRIMARY KEY,
password varchar(512)
);
# Table holding shared secrets for secret-based authorization
# (REST API). It can only be used together with the long-term
# mechanism:
#
CREATE TABLE turn_secret (
realm varchar(512),
value varchar(512),
primary key (realm,value)
);
# Table holding "white" allowed peer IP ranges.
#
CREATE TABLE allowed_peer_ip (
ip_range varchar(256),
primary key (ip_range)
);
# Table holding "black" denied peer IP ranges.
#
CREATE TABLE denied_peer_ip (
ip_range varchar(256),
primary key (ip_range)
);
# Table to match origin to realm.
# Multiple origins may have the same realm.
# If no realm is found or the origin is absent
# then the default realm is used.
#
CREATE TABLE turn_origin_to_realm (
origin varchar(512),
realm varchar(512),
primary key (origin,realm)
);
# Realm options.
# Valid options are 'max-bps',
# 'total-quota' and 'user-quota'.
# Values for them are integers (in text form).
#
CREATE TABLE turn_realm_option (
realm varchar(512),
opt varchar(32),
value varchar(128),
primary key (realm,opt)
);
The field hmackey contains HEX string representation of the key.
We do not store the user open passwords for long-term credentials, for security reasons.
Storing only the HMAC key has its own implications - if you change the realm,
you will have to update the HMAC keys of all users, because the realm is
used for the HMAC key generation.
The key must be 32 characters (HEX representation of 16 bytes) for SHA1,
or 64 characters (HEX representation of 32 bytes) for SHA256.
You can use turnadmin program to manage the database - you can either use
turnadmin to add/modify/delete users, or you can use turnadmin to produce
the hmac keys and modify the database with your favorite tools.
More examples of database schema creation:
psql -h <host> -U <db-user> -d <database-name> < turndb/schema.sql
(old style for 8.4)
psql postgresql://username:password@/databasename < turndb/schema.sql
(newer style for 9.x, UNIX domain local sockets)
Or:
psql postgresql://username:password@hostname:port/databasename < turndb/schema.sql
(newer style for 9.x, TCP/IP access)
Below, the string "postgresql://turn:turn@/turn" is the connection URI.
Of course, the administrators can play with the connection string as they want.
When starting the turnserver, the psql-userdb parameter will be, for example:
turnserver ... --psql-userdb="host=localhost dbname=turn user=turn password=turn connect_timeout=30"
Or, for 9.x PostgreSQL versions:
turnserver ... --psql-userdb=postgresql://username:password@/databasename ...
9) You are ready to use the TURN database. The database name is "turn",
the user name is "turn", the user password is "turn". Of course, you can
choose your own names. Now, you will have to use the program turnadmin to fill the
database, or you can do that manually with psql.
Fill in users, for example:
Shared secret for the TURN REST API:
$ bin/turnadmin -s logen -e "host=localhost dbname=turn user=turn password=turn"
Long-term credentials mechanism:
$ bin/turnadmin -a -e "host=localhost dbname=turn user=turn password=turn" -u gorst -r north.gov -p hero
$ bin/turnadmin -a -e "host=localhost dbname=turn user=turn password=turn" -u ninefingers -r north.gov -p youhavetoberealistic
Long-term credentials mechanism with SHA256 extention:
$ bin/turnadmin -a -e "host=localhost dbname=turn user=turn password=turn" -u bethod -r north.gov -p king-of-north --sha256
Short-term credentials mechanism:
$ bin/turnadmin -A -e "host=localhost dbname=turn user=turn password=turn" -u gorst -r north.gov -p hero
$ bin/turnadmin -A -e "host=localhost dbname=turn user=turn password=turn" -u ninefingers -r north.gov -p youhavetoberealistic
XV. 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
same as for PostgreSQL and you can find it in turndb/schema.sql file, or
in the system's PREFIX/share/turnserver/schema.sql file after the turnserver
installation.
The general setup idea is the same as for PostgreSQL case:
1) Check that the mysql server access is OK. Immediately after the MySQL server
installation, it must be accessible, at the very minimum, at the localhost with
the root account.
2) Login into mysql console from root account:
$ sudo bash
# mysql -p mysql
3) Add 'turn' user with 'turn' password (for example):
> create user 'turn'@'localhost' identified by 'turn';
4) Create database 'turn' (for example) and grant privileges to user 'turn':
> create database turn;
> grant all on turn.* to 'turn'@'localhost';
> flush privileges;
Ctrl-D
5) Create database schema:
$ mysql -p -u turn turn < turndb/schema.sql
Enter password: turn
$
6) Fill in users, for example:
Shared secret for the TURN REST API:
$ bin/turnadmin -s logen -M "host=localhost dbname=turn user=turn password=turn"
Long-term credentials mechanism:
$ bin/turnadmin -a -M "host=localhost dbname=turn user=turn password=turn" -u gorst -r north.gov -p hero
$ bin/turnadmin -a -M "host=localhost dbname=turn user=turn password=turn" -u ninefingers -r north.gov -p youhavetoberealistic
Long-term credentials mechanism with SHA256 extention:
$ bin/turnadmin -a -M "host=localhost dbname=turn user=turn password=turn" -u bethod -r north.gov -p king-of-north --sha256
Short-term credentials mechanism:
$ bin/turnadmin -A -M "host=localhost dbname=turn user=turn password=turn" -u gorst -r north.gov -p hero
$ bin/turnadmin -A -M "host=localhost dbname=turn user=turn password=turn" -u ninefingers -r north.gov -p youhavetoberealistic
7) Now we can use mysql in the turnserver.
If the TURN server was compiled with MySQL support, then we can use the
TURN server database parameter --mysql-userdb. The value of this parameter
is a connection string for the MySQL database. As "native" MySQL does not
have such a feature as "connection string", the TURN server parses the
connection string and converts it into MySQL database connection parameter.
The format of the MySQL connection string is:
"host=<host> dbname=<database-name> user=<database-user> password=<database-user-password> port=<port> connect_timeout=<seconds>"
(all parameters are optional)
So, an example of the MySQL database parameter in the TURN server command
line would be:
--mysql-userdb="host=localhost dbname=turn user=turn password=turn connect_timeout=30"
Or in the turnserver.conf file:
mysql-userdb="host=localhost dbname=turn user=turn password=turn connect_timeout=30"
XVI. Redis setup
The Redis setup is well documented on their site http://redis.io.
The TURN Server Redis database schema description can be found
in schema.userdb.redis and schema.stats.redis files. Those files are located
either in the turndb subdirectory of the main source code directory,
or in /usr/local/share/turnserver/ after the installation, or somewhere in /usr/share/
directory, depending on the OS and on the instalation package.
If the TURN server was compiled with Hiredis support (Hiredis is the C client
library for Redis), then we can use the TURN server database parameter
--redis-userdb. The value of this parameter is a connection string
for the Redis database. As "native" Redis does not have such a feature as
"connection string", the TURN server parses the connection string and
converts it into Redis database access parameter. The format of the Redis
connection string is:
"ip=<ip-addr> dbname=<database-number> password=<database-password> port=<port> connect_timeout=<seconds>"
(all parameters are optional)
So, an example of the Redis database parameter in the TURN server command
line would be:
--redis-userdb="ip=127.0.0.1 dbname=0 password=turn connect_timeout=30"
Or in the turnserver.conf file:
redis-userdb="ip=127.0.0.1 dbname=0 password=turn connect_timeout=30"
Redis can be also used for the TURN allocation status check and for status and
traffic notifications.
See the explanation in the turndb/schema.stats.redis file, and an example in
turndb/testredisdbsetup.sh file. One special thing about TURN Redis security setup
is that you can store open passwords for long-term credentials in Redis.
You cannot set open passwords for long-term credentials in MySQL and PostgreSQL -
with those DBs, you have to use the keys only. With Redis, you have a choice -
keys or open passwords.
You also have to take care about Redis connection parameters, the timeout and the
keepalive. The following settings must be in your Redis config file
(/etc/redis.conf or /usr/local/etc/redis.conf):
..........
timeout 0
..........
tcp-keepalive 60
..........
Redis TURN admin commands:
Shared secret for the TURN REST API:
$ bin/turnadmin -s logen -N "host=localhost dbname=0 user=turn password=turn"
Long-term credentials mechanism:
$ bin/turnadmin -a -N "host=localhost dbname=0 user=turn password=turn" -u gorst -r north.gov -p hero
$ bin/turnadmin -a -N "host=localhost dbname=0 user=turn password=turn" -u ninefingers -r north.gov -p youhavetoberealistic
Long-term credentials mechanism with SHA256 extention:
$ bin/turnadmin -a -N "host=localhost dbname=0 user=turn password=turn" -u bethod -r north.gov -p king-of-north --sha256
Short-term credentials mechanism:
$ bin/turnadmin -A -N "host=localhost dbname=0 user=turn password=turn" -u gorst -r north.gov -p hero
$ bin/turnadmin -A -N "host=localhost dbname=0 user=turn password=turn" -u ninefingers -r north.gov -p youhavetoberealistic
XV. Performance tuning
This topic is covered in the wiki page:
http://code.google.com/p/coturn/wiki/turn_performance_and_load_balance
XVI. 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.
XVI. 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
on-the-fly.
You can access that CLI interface with telnet or putty program (in telnet mode).
The process by default listens to port 5766 on IP address 127.0.0.1 for the telnet
connections.
WARNING: all telnet communications are going unencrypted over the network. For
security reasons, we advise using the loopback IP addresses for CLI (127.0.0.1
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.

31
LICENSE Normal file
View File

@ -0,0 +1,31 @@
/*
* TURN Server - RFC5766 TURN Server implementation
* Copyright (C) 2011, 2012, 2013 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.
*/

127
LICENSE.OpenSSL Normal file
View File

@ -0,0 +1,127 @@
LICENSE ISSUES
==============
The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
the OpenSSL License and the original SSLeay license apply to the toolkit.
See below for the actual license texts. Actually both licenses are BSD-style
Open Source licenses. In case of any license issues related to OpenSSL
please contact openssl-core@openssl.org.
OpenSSL License
---------------
/* ====================================================================
* Copyright (c) 1998-2008 The OpenSSL Project. 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. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED 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 OpenSSL PROJECT OR
* ITS 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.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
Original SSLeay License
-----------------------
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* 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 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/

173
Makefile.in Executable file
View File

@ -0,0 +1,173 @@
LIBEVENT_INCLUDE = -I${PREFIX}/include/ -I/usr/local/include/
INCFLAGS = -Isrc -Isrc/apps/common -Isrc/server -Isrc/client -Isrc/client++ ${LIBEVENT_INCLUDE}
CFLAGS += ${INCFLAGS}
MAKE_DEPS = Makefile
LIBCLIENTTURN_HEADERS = src/ns_turn_defs.h src/client++/TurnMsgLib.h src/client/ns_turn_ioaddr.h src/client/ns_turn_msg.h src/client/ns_turn_msg_defs.h src/client/ns_turn_msg_addr.h
LIBCLIENTTURN_MODS = src/client/ns_turn_ioaddr.c src/client/ns_turn_msg_addr.c src/client/ns_turn_msg.c
LIBCLIENTTURN_DEPS = ${LIBCLIENTTURN_HEADERS} ${MAKE_DEPS}
LIBCLIENTTURN_OBJS = build/obj/ns_turn_ioaddr.o build/obj/ns_turn_msg_addr.o build/obj/ns_turn_msg.o
SERVERTURN_HEADERS = src/server/ns_turn_allocation.h src/server/ns_turn_ioalib.h src/server/ns_turn_khash.h src/server/ns_turn_maps_rtcp.h src/server/ns_turn_maps.h src/server/ns_turn_server.h src/server/ns_turn_session.h
SERVERTURN_DEPS = ${LIBCLIENTTURN_HEADERS} ${SERVERTURN_HEADERS} ${MAKE_DEPS}
SERVERTURN_MODS = ${LIBCLIENTTURN_MODS} src/server/ns_turn_allocation.c src/server/ns_turn_maps_rtcp.c src/server/ns_turn_maps.c src/server/ns_turn_server.c
COMMON_HEADERS = src/apps/common/apputils.h src/apps/common/ns_turn_utils.h src/apps/common/stun_buffer.h
COMMON_MODS = src/apps/common/apputils.c src/apps/common/ns_turn_utils.c src/apps/common/stun_buffer.c
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
IMPL_DEPS = ${COMMON_DEPS} ${IMPL_HEADERS} ${IMPL_MODS}
HIREDIS_HEADERS = src/apps/common/hiredis_libevent2.h
HIREDIS_MODS = src/apps/common/hiredis_libevent2.c
SERVERAPP_HEADERS = src/apps/relay/userdb.h src/apps/relay/tls_listener.h src/apps/relay/mainrelay.h src/apps/relay/turncli.h src/apps/relay/dtls_listener.h src/apps/relay/libtelnet.h ${HIREDIS_HEADERS}
SERVERAPP_MODS = src/apps/relay/mainrelay.c src/apps/relay/netengine.c src/apps/relay/libtelnet.c src/apps/relay/turncli.c src/apps/relay/userdb.c src/apps/relay/tls_listener.c src/apps/relay/dtls_listener.c ${HIREDIS_MODS}
SERVERAPP_DEPS = ${SERVERTURN_MODS} ${SERVERTURN_DEPS} ${SERVERAPP_MODS} ${SERVERAPP_HEADERS} ${COMMON_DEPS} ${IMPL_DEPS} lib/libturnclient.a
TURN_BUILD_RESULTS = bin/turnutils_stunclient bin/turnutils_rfc5769check bin/turnutils_uclient bin/turnserver bin/turnutils_peer lib/libturnclient.a include/turn/ns_turn_defs.h
all: ${TURN_BUILD_RESULTS}
test: check
check: bin/turnutils_rfc5769check
bin/turnutils_rfc5769check
include/turn/ns_turn_defs.h: src/ns_turn_defs.h
${RMCMD} include
${MKBUILDDIR} include/turn/client
cp -pf src/client/*.h include/turn/client/
cp -pf src/client++/*.h include/turn/client/
cp -pf src/ns_turn_defs.h include/turn/
bin/turnutils_uclient: ${COMMON_DEPS} src/apps/uclient/session.h lib/libturnclient.a src/apps/uclient/mainuclient.c src/apps/uclient/uclient.c src/apps/uclient/uclient.h src/apps/uclient/startuclient.c src/apps/uclient/startuclient.h
${MKBUILDDIR} bin
${CC} ${CPPFLAGS} ${CFLAGS} src/apps/uclient/uclient.c src/apps/uclient/startuclient.c src/apps/uclient/mainuclient.c ${COMMON_MODS} -o $@ -Llib -lturnclient -Llib ${LDFLAGS}
bin/turnutils_stunclient: ${COMMON_DEPS} lib/libturnclient.a src/apps/stunclient/stunclient.c
pwd
${MKBUILDDIR} bin
${CC} ${CPPFLAGS} ${CFLAGS} src/apps/stunclient/stunclient.c ${COMMON_MODS} -o $@ -Llib -lturnclient -Llib ${LDFLAGS}
bin/turnutils_rfc5769check: ${COMMON_DEPS} lib/libturnclient.a src/apps/rfc5769/rfc5769check.c
pwd
${MKBUILDDIR} bin
${CC} ${CPPFLAGS} ${CFLAGS} src/apps/rfc5769/rfc5769check.c ${COMMON_MODS} -o $@ -Llib -lturnclient -Llib ${LDFLAGS}
bin/turnserver: ${SERVERAPP_DEPS}
${MKBUILDDIR} bin
${RMCMD} bin/turnadmin
${CC} ${CPPFLAGS} ${CFLAGS} ${DBCFLAGS} ${IMPL_MODS} -Ilib ${SERVERAPP_MODS} ${COMMON_MODS} ${SERVERTURN_MODS} -o $@ ${DBLIBS} ${LDFLAGS}
cd bin; ln -s turnserver turnadmin
bin/turnutils_peer: ${COMMON_DEPS} ${LIBCLIENTTURN_MODS} ${LIBCLIENTTURN_DEPS} lib/libturnclient.a src/apps/peer/mainudpserver.c src/apps/peer/udpserver.h src/apps/peer/udpserver.c
${MKBUILDDIR} bin
${CC} ${CPPFLAGS} ${CFLAGS} src/apps/peer/mainudpserver.c src/apps/peer/udpserver.c ${COMMON_MODS} -o $@ -Llib -lturnclient -Llib ${LDFLAGS}
### Client Library:
lib/libturnclient.a: ${LIBCLIENTTURN_OBJS} ${LIBCLIENTTURN_DEPS}
${MKBUILDDIR} lib
${ARCHIVERCMD} $@ ${LIBCLIENTTURN_OBJS}
build/obj/ns_turn_ioaddr.o: src/client/ns_turn_ioaddr.c ${LUBCLIENTTURN_DEPS}
${MKBUILDDIR} build/obj
${CC} ${CPPFLAGS} ${CFLAGS} -c src/client/ns_turn_ioaddr.c -o $@
build/obj/ns_turn_msg_addr.o: src/client/ns_turn_msg_addr.c ${LUBCLIENTTURN_DEPS}
${MKBUILDDIR} build/obj
${CC} ${CPPFLAGS} ${CFLAGS} -c src/client/ns_turn_msg_addr.c -o $@
build/obj/ns_turn_msg.o: src/client/ns_turn_msg.c ${LUBCLIENTTURN_DEPS}
${MKBUILDDIR} build/obj
${CC} ${CPPFLAGS} ${CFLAGS} -c src/client/ns_turn_msg.c -o $@
### Clean all:
clean:
${RMCMD} bin build lib obj *bak *~ */*~ */*/*~ */*/*/*~ *core */*core */*/*core include Makefile tmp
distclean: clean
### Install all:
install: all ${MAKE_DEPS}
${MKDIR} ${DESTDIR}${PREFIX}
${MKDIR} ${DESTDIR}${BINDIR}
${MKDIR} ${DESTDIR}${MANPREFIX}/man/man1
${MKDIR} ${DESTDIR}${CONFDIR}
${MKDIR} ${DESTDIR}${LIBDIR}
${MKDIR} ${DESTDIR}${EXAMPLESDIR}
${MKDIR} ${DESTDIR}${DOCSDIR}
${MKDIR} ${DESTDIR}${SCHEMADIR}
${MKDIR} ${DESTDIR}${TURNINCLUDEDIR}
${INSTALL_PROGRAM} bin/turnserver ${DESTDIR}${BINDIR}
${INSTALL_PROGRAM} bin/turnadmin ${DESTDIR}${BINDIR}
${INSTALL_PROGRAM} bin/turnutils_uclient ${DESTDIR}${BINDIR}
${INSTALL_PROGRAM} bin/turnutils_peer ${DESTDIR}${BINDIR}
${INSTALL_PROGRAM} bin/turnutils_stunclient ${DESTDIR}${BINDIR}
${INSTALL_MAN} man/man1/turnserver.1 ${DESTDIR}${MANPREFIX}/man/man1/
${INSTALL_MAN} man/man1/turnadmin.1 ${DESTDIR}${MANPREFIX}/man/man1/
${INSTALL_MAN} man/man1/turnutils.1 ${DESTDIR}${MANPREFIX}/man/man1/
${INSTALL_MAN} man/man1/turnutils_uclient.1 ${DESTDIR}${MANPREFIX}/man/man1/
${INSTALL_MAN} man/man1/turnutils_stunclient.1 ${DESTDIR}${MANPREFIX}/man/man1/
${INSTALL_MAN} man/man1/turnutils_peer.1 ${DESTDIR}${MANPREFIX}/man/man1/
${INSTALL_MAN} man/man1/coturn.1 ${DESTDIR}${MANPREFIX}/man/man1/
${INSTALL_STATIC_LIB} lib/libturnclient.a ${DESTDIR}${LIBDIR}
${INSTALL_DATA} LICENSE ${DESTDIR}${DOCSDIR}
${INSTALL_DATA} README.turnserver ${DESTDIR}${DOCSDIR}
${INSTALL_DATA} README.turnadmin ${DESTDIR}${DOCSDIR}
${INSTALL_DATA} README.turnutils ${DESTDIR}${DOCSDIR}
${INSTALL_DATA} INSTALL ${DESTDIR}${DOCSDIR}
${INSTALL_DATA} postinstall.txt ${DESTDIR}${DOCSDIR}
${INSTALL_DATA} turndb/schema.sql ${DESTDIR}${DOCSDIR}
${INSTALL_DATA} turndb/schema.sql ${DESTDIR}${SCHEMADIR}
${INSTALL_DATA} turndb/testredisdbsetup.sh ${DESTDIR}${SCHEMADIR}
${INSTALL_DATA} turndb/testsqldbsetup.sql ${DESTDIR}${SCHEMADIR}
${INSTALL_DATA} turndb/schema.userdb.redis ${DESTDIR}${DOCSDIR}
${INSTALL_DATA} turndb/schema.userdb.redis ${DESTDIR}${SCHEMADIR}
${INSTALL_DATA} turndb/schema.stats.redis ${DESTDIR}${DOCSDIR}
${INSTALL_DATA} turndb/schema.stats.redis ${DESTDIR}${SCHEMADIR}
${INSTALL_DATA} examples/etc/turnserver.conf ${DESTDIR}${CONFDIR}/turnserver.conf.default
${INSTALL_DATA} examples/etc/turnuserdb.conf ${DESTDIR}${CONFDIR}/turnuserdb.conf.default
${INSTALL_DIR} examples/etc ${DESTDIR}${EXAMPLESDIR}
${INSTALL_DIR} examples/scripts ${DESTDIR}${EXAMPLESDIR}
${RMCMD} ${DESTDIR}${EXAMPLESDIR}/scripts/rfc5769.sh
${INSTALL_DIR} include/turn/client ${DESTDIR}${TURNINCLUDEDIR}
${INSTALL_DATA} include/turn/ns_turn_defs.h ${DESTDIR}${TURNINCLUDEDIR}
${MORECMD} ${DESTDIR}${DOCSDIR}/postinstall.txt
deinstall: ${MAKE_DEPS}
${PKILL_PROGRAM} turnserver || ${ECHO_CMD} OK
${RMCMD} ${DESTDIR}${DOCSDIR}
${RMCMD} ${DESTDIR}${SCHEMADIR}
${RMCMD} ${DESTDIR}${BINDIR}/turnserver
${RMCMD} ${DESTDIR}${BINDIR}/turnadmin
${RMCMD} ${DESTDIR}${BINDIR}/turnutils_peer
${RMCMD} ${DESTDIR}${BINDIR}/turnutils_uclient
${RMCMD} ${DESTDIR}${BINDIR}/turnutils_stunclient
${RMCMD} ${DESTDIR}${MANPREFIX}/man/man1/turnserver.1
${RMCMD} ${DESTDIR}${MANPREFIX}/man/man1/turnadmin.1
${RMCMD} ${DESTDIR}${MANPREFIX}/man/man1/turnutils.1
${RMCMD} ${DESTDIR}${MANPREFIX}/man/man1/turnutils_uclient.1
${RMCMD} ${DESTDIR}${MANPREFIX}/man/man1/turnutils_stunclient.1
${RMCMD} ${DESTDIR}${MANPREFIX}/man/man1/turnutils_peer.1
${RMCMD} ${DESTDIR}${MANPREFIX}/man/man1/coturn.1
${RMCMD} ${DESTDIR}${LIBDIR}/libturnclient.a
${RMCMD} ${DESTDIR}${EXAMPLESDIR}/
${RMCMD} ${DESTDIR}${CONFDIR}/turnserver.conf.default
${RMCMD} ${DESTDIR}${CONFDIR}/turnuserdb.conf.default
${RMCMD} ${DESTDIR}${TURNINCLUDEDIR}
uninstall: deinstall
reinstall: deinstall install

2
NOTE Normal file
View File

@ -0,0 +1,2 @@
This project is active in Google code: http://code.google.com/p/coturn/

239
README.turnadmin Normal file
View File

@ -0,0 +1,239 @@
GENERAL INFORMATION
turnadmin is a TURN administration tool. This tool can be used to manage
the user accounts (add/remove users, generate
TURN keys for the users). For security reasons, we do not recommend
storing passwords openly. The better option is to use pre-processed "keys"
which are then used for authentication. These keys are generated by turnadmin.
Turnadmin is a link to turnserver binary, but turnadmin performs different
functions.
Options note: turnadmin has long and short option names, for most options.
Some options have only long form, some options have only short form. Their syntax
somewhat different, if an argument is required:
The short form must be used as this (for example):
$ turnadmin -u <username> ...
The long form equivalent must use the "=" character:
$ turnadmin --user=<username> ...
If this is a flag option (no argument required) then their usage are the same, for example:
$ turnadmin -k ...
is equivalent to:
$ turnadmin --key ...
You have always the use the -r <realm> option with commands for long term credentials -
because data for multiple realms can be stored in the same database.
=====================================
NAME
turnadmin - a TURN relay administration tool.
SYNOPSIS
$ turnadmin [command] [options]
$ turnadmin [ -h | --help]
DESCRIPTION
Commands:
-k, --key Generate key for a long-term credentials mechanism user.
-a, --add Add or update a long-term user.
-A, --add-st Add or update a short-term credentials mechanism user.
-d, --delete Delete a long-term user.
-D, --delete-st Delete a short-term user.
-l, --list List long-term users in the database.
-L, --list-st List short-term users in the database.
-s, --set-secret=<value> Add shared secret for TURN RESP API
-S, --show-secret Show stored shared secrets for TURN REST API
-X, --delete-secret=<value> Delete a shared secret.
--delete-all_secrets Delete all shared secrets for REST API.
-O, --add-origin Add origin-to-realm relation.
-R, --del-origin Delete origin-to-realm relation.
-I, --list-origins List origin-to-realm relations.
-g, --set-realm-option Set realm params: max-bps, total-quota, user-quota.
-G, --list-realm-options List realm params.
NOTE: if you are using the flat file for the user database, then you will have
to use a text editor to set or show the shared secrets.
NOTE: the origin functionality is not supported with flat user db file,
a "real" database must be used.
Options with required values:
-b, --userdb File-based user database file name (default - turnuserdb.conf).
See the --userdb option in the turnserver section.
-e, --psql-userdb PostgreSQL user database connection string.
See the --psql-userdb option in the turnserver section.
-M, --mysql-userdb MySQL user database connection string.
See the --mysql-userdb option in the turnserver section.
-N, --redis-userdb Redis user database connection string.
See the --redis-userdb option in the turnserver section.
-u, --user User name.
-r, --realm Realm, for long-term credentials mechanism only.
-p, --password Password.
-o, --origin Origin
-H, --sha256 Use SHA256 as the keys hash function (a non-standard feature).
By default, MD5 is used for the key storage encryption
(as required by the current STUN/TURNstandards).
--max-bps Set value of realm's max-bps parameter.
--total-quota Set value of realm's total-quota parameter.
--user-quota Set value of realm's user-quota parameter.
-h, --help Help.
Generate a key:
$ turnadmin -k -u <username> -r <realm> -p <password>
Add/update a user in the userdb file or in the database:
$ turnadmin -a [-b <userdb-file> | -e <db-connection-string> | -M <db-connection-string> | -N <db-connection-string> ] -u <username> -r <realm> -p <password>
Delete a user from the userdb file or from the database:
$ turnadmin -d [-b <userdb-file> | -e <db-connection-string> | -M <db-connection-string> | -N <db-connection-string> ] -u <username> -r <realm>
List all long-term users in MySQL database:
$ turnadmin -l --mysql-userdb="<db-connection-string>" -r <realm>
List all short-term users in Redis database:
$ turnadmin -L --redis-userdb="<db-connection-string>"
Set secret in MySQL database:
$ turnadmin -s <secret> --mysql-userdb="<db-connection-string>" -r <realm>
Show secret stored in PostgreSQL database:
$ turnadmin -S --psql-userdb="<db-connection-string>" -r <realm>
Set origin-to-realm relation in MySQL database:
$ turnadmin --mysql-userdb="<db-connection-string>" -r <realm> -o <origin>
Delete origin-to-realm relation from Redis DB:
$ turnadmin --redis-userdb="<db-connection-string>" -o <origin>
List all origin-to-realm relations in Redis DB:
$ turnadmin --redis-userdb="<db-connection-string>" -I
List the origin-to-realm relations in PostgreSQL DB for a single realm:
$ turnadmin --psql-userdb="<db-connection-string>" -I -r <realm>
Help:
$ turnadmin -h
=======================================
DOCS
After installation, run the command:
$ man turnadmin
or in the project root directory:
$ man -M man turnadmin
to see the man page.
=====================================
FILES
/etc/turnserver.conf
/etc/turnuserdb.conf
/usr/local/etc/turnserver.conf
/usr/local/etc/turnuserdb.conf
=====================================
DIRECTORIES
/usr/local/share/turnserver
/usr/local/share/doc/turnserver
/usr/local/share/examples/turnserver
======================================
SEE ALSO
turnserver, turnutils
======================================
WEB RESOURCES
project page:
http://code.google.com/p/coturn/
Wiki page:
http://code.google.com/p/coturn/wiki/Readme
forum:
https://groups.google.com/forum/?fromgroups=#!forum/turn-server-project-rfc5766-turn-server/
======================================
AUTHORS
Oleg Moskalenko <mom040267@gmail.com>
Gabor Kovesdan http://kovesdan.org/
Daniel Pocock http://danielpocock.com/
John Selbie (jselbie@gmail.com)
Lee Sylvester <lee@designrealm.co.uk>
Erik Johnston <erikj@openmarket.com>
Roman Lisagor <roman@demonware.net>
Vladimir Tsanev <tsachev@gmail.com>
Po-sheng Lin <personlin118@gmail.com>
Peter Dunkley <peter.dunkley@crocodilertc.net>
Mutsutoshi Yoshimoto <mutsutoshi.yoshimoto@mixi.co.jp>

880
README.turnserver Normal file
View File

@ -0,0 +1,880 @@
GENERAL INFORMATION
The TURN Server project contains the source code of a TURN server and TURN client
messaging library. Also, some extra programs provided, for testing-only
purposes.
See the INSTALL file for the building instructions.
After the build, you will have the following binary images:
1. turnserver: TURN Server relay.
The compiled binary image of the TURN Server program is located in bin/ sub-directory.
2. turnadmin: TURN administration tool. See README.turnadmin and turnadmin man page.
3. turnutils_uclient. See README.turnutils and turnutils man page.
4. turnutils_peer. See README.turnutils and turnutils man page.
5. turnutils_stunclient. See README.turnutils and turnutils man page.
6. turnutils_rfc5769check. See README.turnutils and turnutils man page.
In the "examples/scripts" sub-directory, you will find the examples of command lines to be used
to run the programs. The scripts are meant to be run from examples/ sub-directory, for example:
$ cd examples
$ ./scripts/secure_relay.sh
RUNNING THE TURN SERVER
Options note: turnserver has long and short option names, for most options.
Some options have only long form, some options have only short form. Their syntax
somewhat different, if an argument is required:
The short form must be used as this (for example):
$ turnserver -L 12.34.56.78
The long form equivalent must use the "=" character:
$ turnserver --listening-ip=12.34.56.78
If this is a flag option (no argument required) then their usage are the same, for example:
$ turnserver -a
is equivalent to:
$ turnserver --lt-cred-mech
=====================================
NAME
turnserver - a TURN relay server implementation.
SYNOPSIS
$ turnserver [-n | -c <config-file> ] [flags] [ --userdb=<userdb-file> | --psql-userdb=<db-conn-string> | --mysql-userdb=<db-conn-string> | --redis-userdb=<db-conn-string> ] [-z | --no-auth | -a | --lt-cred-mech ] [options]
$ turnserver -h
DESCRIPTION
Config file settings:
-n Do not use configuration file, use only command line parameters.
-c Configuration file name (default - turnserver.conf).
The format of config file can be seen in
the supplied examples/etc/turnserver.conf example file. Long
names of the options are used as the configuration
items names in the file. If not an absolute path is supplied,
then the file is searched in the following directories:
* current directory
* current directory etc/ sub-directory
* upper directory level etc/
* /etc/
* /usr/local/etc/
* installation directory /etc
User database settings:
-b, --userdb User database file name (default - turnuserdb.conf),
for long-term credentials mechanism only.
This user file database is being dynamically checked while the turnserver
is working, and the user accounts can be changed dynamically by
editing the database.
-e, --psql-userdb User database connection string for PostgreSQL.
This database can be used for long-term and short-term credentials mechanisms,
and it can store the secret value for secret-based timed authentication in TURN RESP API.
The connection string format is like that:
"host=<host> dbname=<dbname> user=<db-user> password=<db-user-password> connect_timeout=<seconds>"
(for 8.x or newer Postgres).
Or:
"postgresql://username:password@hostname:port/databasename" (for 9.x or newer Postgres).
See the INSTALL file for more explanations and examples.
Also, see http://www.PostgreSQL.org for full PostgreSQL documentation.
-M, --mysql-userdb User database connection string for MySQL or MariaDB.
This database can be used for long-term and short-term credentials mechanisms,
and it can store the secret value for secret-based timed authentication in TURN RESP API.
The connection string format is like that:
"host=<host> dbname=<dbname> user=<db-user> password=<db-user-password> connect_timeout=<seconds>"
See the INSTALL file for more explanations and examples.
Also, see http://www.mysql.org or http://mariadb.org
for full MySQL documentation.
-N, --redis-userdb User database connection string for Redis.
This database can be used for long-term and short-term credentials mechanisms,
and it can store the secret value for secret-based timed authentication in TURN RESP API.
The connection string format is like that:
"ip=<ip-addr> dbname=<db-number> password=<db-password> connect_timeout=<seconds>"
See the INSTALL file for more explanations and examples.
Also, see http://redis.io for full Redis documentation.
Flags:
-v, --verbose Moderate verbose mode.
-V, --Verbose Extra verbose mode, very annoying and not recommended.
-o, --daemon Run server as daemon.
-f, --fingerprint Use fingerprints in the TURN messages. If an incoming request
contains a fingerprint, then TURN server will always add
fingerprints to the messages in this session, regardless of the
per-server setting.
-a, --lt-cred-mech Use long-term credentials mechanism (this one you need for WebRTC usage).
This option can be used with either flat file user database or
PostgreSQL DB or MySQL DB or Redis for user keys storage.
-A, --st-cred-mech Use the short-term credentials mechanism. This option requires
a PostgreSQL or MySQL or Redis DB for short term passwords storage.
-z, --no-auth Do not use any credentials mechanism, allow anonymous access.
Opposite to -a and -A options. This is default option when no
authentication-related options are set.
By default, no credential mechanism is used -
any user is allowed.
--use-auth-secret TURN REST API flag.
Flag that sets a special WebRTC authorization option
that is based upon authentication secret. The feature purpose
is to support "TURN Server REST API" as described in
the TURN REST API section below.
This option uses timestamp as part of combined username:
usercombo -> "timestamp:username",
turn user -> usercombo,
turn password -> base64(hmac(secret key, usercombo)).
This allows TURN credentials to be accounted for a specific user id.
If you don't have a suitable id, the timestamp alone can be used.
This option is just turns on secret-based authentication.
The actual value of the secret is defined either by option static-auth-secret,
or can be found in the turn_secret table in the database.
This option can be used with long-term credentials mechanisms only -
it does not make much sense with the short-term mechanism.
--dh566 Use 566 bits predefined DH TLS key. Default size of the key is 1066.
--dh2066 Use 2066 bits predefined DH TLS key. Default size of the key is 1066.
--no-sslv2 Do not allow SSLv2 protocol.
--no-sslv3 Do not allow SSLv3 protocol.
--no-tlsv1 Do not allow TLSv1 protocol.
--no-tlsv1_1 Do not allow TLSv1.1 protocol.
--no-tlsv1_2 Do not allow TLSv1.2 protocol.
--no-udp Do not start UDP client listeners.
--no-tcp Do not start TCP client listeners.
--no-tls Do not start TLS client listeners.
--no-dtls Do not start DTLS client listeners.
--no-udp-relay Do not allow UDP relay endpoints defined in RFC 5766,
use only TCP relay endpoints as defined in RFC 6062.
--no-tcp-relay Do not allow TCP relay endpoints defined in RFC 6062,
use only UDP relay endpoints as defined in RFC 5766.
--stale-nonce Use extra security with nonce value having limited lifetime (600 secs).
--no-stdout-log Flag to prevent stdout log messages.
By default, all log messages are going to both stdout and to
the configured log file. With this option everything will be going to
the log file only (unless the log file itself is stdout).
--syslog With this flag, all log will be redirected to the system log (syslog).
--simple-log This flag means that no log file rollover will be used, and the log file
name will be constructed as-is, without PID and date appendage.
--secure-stun Require authentication of the STUN Binding request.
By default, the clients are allowed anonymous access to the STUN Binding functionality.
-S, --stun-only Run as STUN server only, all TURN requests will be ignored.
Option to suppress TURN functionality, only STUN requests will be processed.
--no-stun Run as TURN server only, all STUN requests will be ignored.
Option to suppress STUN functionality, only TURN requests will be processed.
--no-loopback-peers Disallow peers on the loopback addresses (127.x.x.x and ::1).
--no-multicast-peers Disallow peers on well-known broadcast addresses
(224.0.0.0 and above, and FFXX:*).
--sha256 Require SHA256 digest function to be used for the message integrity.
By default, the server uses SHA1 hashes. With this option, the server
requires the stronger SHA256 hashes. The client application must support
SHA256 hash function if this option is used. If the server obtains a message
from the client with a weaker (SHA1) hash function then the server returns
error code 426.
--mobility Mobility with ICE (MICE) specs support.
--no-cli Turn OFF the CLI support. By default it is always ON.
See also options --cli-ip and --cli-port.
--server-relay Server relay. NON-STANDARD AND DANGEROUS OPTION.
Only for those applications when we want to run
server applications on the relay endpoints.
This option eliminates the IP permissions check
on the packets incoming to the relay endpoints.
See http://tools.ietf.org/search/rfc5766#section-17.2.3 .
--udp-self-balance (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 functionality.
-h Help.
Options with required values:
-d, --listening-device Listener interface device.
(NOT RECOMMENDED. Optional functionality, Linux only).
The turnserver process must have root privileges to bind the
listening endpoint to a device. If turnserver must run as a
process without root privileges, then just do not use this setting.
-L, --listening-ip Listener IP address of relay server.
Multiple listeners can be specified, for example:
-L ip1 -L ip2 -L ip3
If no IP(s) specified, then all IPv4 and
IPv6 system IPs will be used for listening.
The same ip(s) can be used as both listening and relay ip(s).
-p, --listening-port TURN listener port for UDP and TCP listeners (Default: 3478).
Note: actually, TLS & DTLS sessions can connect to the "plain" TCP & UDP
port(s), too - if allowed by configuration.
--tls-listening-port TURN listener port for TLS and DTLS listeners (Default: 5349).
Note: actually, "plain" TCP & UDP sessions can connect to the TLS & DTLS
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 we keep both endpoints to satisfy the RFC 5766 specs.
For secure TCP connections, we currently support SSL version 3 and
TLS versions 1.0, 1.1, 1.2. SSL2 "encapsulation mode" is also supported.
For secure UDP connections, we support DTLS version 1.
--alt-listening-port Alternative listening port for UDP and TCP listeners;
default (or zero) value means "listening port plus one".
This is needed for STUN CHANGE_REQUEST - in RFC 5780 sense
or in old RFC 3489 sense - for NAT behavior discovery). The TURN Server
supports CHANGE_REQUEST only if it is started with more than one
listening IP address of the same family (IPv4 or IPv6). The CHANGE_REQUEST
is only supported by UDP protocol, other protocols are listening
on that endpoint only for "symmetry".
--alt-tls-listening-port Alternative listening port for TLS and DTLS protocols.
Default (or zero) value means "TLS listening port plus one".
--aux-server Auxiliary STUN/TURN server listening endpoint.
Aux servers have almost full TURN and STUN functionality.
The (minor) limitations are:
1) Auxiliary servers do not have alternative ports and
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
to client requests.
-i, --relay-device Relay interface device for relay sockets
(NOT RECOMMENDED. Optional, Linux only).
-E, --relay-ip Relay address (the local IP address that
will be used to relay the packets to the
peer). Multiple relay addresses may be used:
-E ip1 -E ip2 -E ip3
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 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).
-X, --external-ip TURN Server public/private address mapping, if the server is behind NAT.
In that situation, if a -X is used in form "-X <ip>" then that ip will be reported
as relay IP address of all allocations. This scenario works only in a simple case
when one single relay address is be used, and no CHANGE_REQUEST functionality is
required. That single relay address must be mapped by NAT to the 'external' IP.
The "external-ip" value, if not empty, is returned in XOR-RELAYED-ADDRESS field.
For that 'external' IP, NAT must forward ports directly (relayed port 12345
must be always mapped to the same 'external' port 12345).
In more complex case when more than one IP address is involved,
that option must be used several times, each entry must
have form "-X <public-ip/private-ip>", to map all involved addresses.
CHANGE_REQUEST (RFC5780 or RFC3489) NAT discovery STUN functionality will work
correctly, 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.
-m, --relay-threads Number of relay threads to handle the established connections
(in addition to authentication thread and the listener thread).
If 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). In older systems (before Linux kernel 3.9),
the number of UDP threads is always one threads per network listening endpoint -
unless "-m 0" or "-m 1" is set.
--min-port Lower bound of the UDP port range for relay
endpoints allocation.
Default value is 49152, according to RFC 5766.
--max-port Upper bound of the UDP port range for relay
endpoints allocation.
Default value is 65535, according to RFC 5766.
-u, --user Long-term security mechanism credentials user account,
in the column-separated form username:key.
Multiple user accounts may used in the command line.
The key is either the user password, or
the key is generated
by turnadmin command. In the second case,
the key must be prepended with 0x symbols.
The key is calculated over the user name,
the user realm, and the user password.
This setting may not be used with TURN REST API or
with short-term credentials mechanism.
-r, --realm The default realm to be used for the users when no explicit
origin/realm relationship was 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
mechanism or with TURN REST API.
-C, --rest-api-separator This is the timestamp/username separator symbol (character) in TURN REST API.
The default value is :.
-q, --user-quota Per-user allocations quota: how many concurrent
allocations a user can create. This option can also be set
through the database, for a particular realm.
-Q, --total-quota Total allocations quota: global limit on concurrent allocations.
This option can also be set through the database, for a particular realm.
-s, --max-bps Max bytes-per-second bandwidth a TURN session is allowed to handle
(input and output network streams are treated separately). Anything above
that limit will be dropped or temporary suppressed (within the
available buffer limits). This option can also be set through the
database, for a particular realm.
--static-auth-secret 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 turn_secret table in user database (if present). The database-stored
value can be changed on-the-fly by a separate program, so this is why
that other mode is dynamic. Multiple shared secrets can be used
(both in the database and in the "static" fashion).
--cert Certificate file, PEM format. Same file
search rules applied as for the configuration
file. If both --no-tls and --no-dtls options
are specified, then this parameter is not needed.
Default value is turn_server_cert.pem.
--pkey Private key file, PEM format. Same file
search rules applied as for the configuration
file. If both --no-tls and --no-dtls options
are specified, then this parameter is not needed.
Default value is turn_server_pkey.pem.
--pkey-pwd If the private key file is encrypted, then this password to be used.
--cipher-list Allowed OpenSSL cipher list for TLS/DTLS connections.
Default value is "DEFAULT".
--CA-file CA file in OpenSSL format.
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.
--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.
-l, --log-file Option to set the full path name of the log file.
By default, the turnserver tries to open a log file in
/var/log/turnserver, /var/log, /var/tmp, /tmp and . (current)
directories (which file open operation succeeds
first that file will be used). With this option you can set the
definite log file name.
The special names are "stdout" and "-" - they will force everything
to the stdout. Also, "syslog" name will redirect everything into
the system log (syslog), as if the option "--syslog" was set.
--alternate-server Option to set the "redirection" mode. The value of this option
will be the address of the alternate server for UDP & TCP service in form of
<ip>[:<port>]. 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 ALTERNATE-SERVER functionality description.
The client must use the obtained value for subsequent TURN communications.
If more than one --alternate-server options are 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
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 .
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 we have 4 alternate servers,
then each server will receive 25% of ALLOCATE requests. An alternate TURN server
address can be used more than one time with the alternate-server option, so this
can emulate "weighting" of the servers.
--tls-alternate-server Option to set alternative server for TLS & DTLS services in form of
<ip>:<port>. 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.
-O, --redis-statsdb 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.
This database option can be used independently of --redis-userdb option,
and actually Redis can be used for status/statistics and MySQL or PostgreSQL can
be used for the user database.
The connection string has the same parameters as redis-userdb connection string.
--max-allocate-timeout Max time, in seconds, allowed for full allocation establishment.
Default is 60 seconds.
--denied-peer-ip=<IPaddr[-IPaddr]>
--allowed-peer-ip=<IPaddr[-IPaddr]> Options to ban or allow 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
internet (e.g. when the turn server is sitting behind a NAT). The 'white" and "black" peer
IP ranges can also be dynamically changed in the database.
The allowed/denied addresses (white/black lists) rules are very simple:
1) If there is no rule for an address, then it is allowed;
2) If there is an "allowed" rule that fits the address then it is allowed - no matter what;
3) If there is no "allowed" rule that fits the address, and if there is a "denied" rule that
fits the address, then it is denied.
--pidfile 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 .
--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.
--proc-group Group name to run the process. After the initialization, the turnserver process
will make an attempt to change the current group ID to that group.
--cli-ip Local system IP address to be used for CLI management interface.
The turnserver process can be accessed for management with telnet,
at this IP address and on the CLI port (see the next parameter).
Default value is 127.0.0.1. You can use telnet or putty (in telnet mode)
to access the CLI management interface.
--cli-port CLI management interface listening port. Default is 5766.
--cli-password CLI access password. Default is empty (no password).
--cli-max-output-sessions Maximum number of output sessions in ps CLI command.
This value can be changed on-the-fly in CLI. The default value is 256.
--ne=[1|2|3] Set network engine type for the process (for internal purposes).
==================================
LOAD BALANCE AND PERFORMANCE TUNING
This topic is covered in the wiki page:
http://code.google.com/p/coturn/wiki/turn_performance_and_load_balance
===================================
WEBRTC USAGE
This is a set of notes for the WebRTC users:
1) WebRTC uses long-term authentication mechanism, so you have to use -a
option (or --lt-cred-mech). WebRTC relaying will not work with anonymous access
or with short-term authentication. With -a option, do not forget to set the
default realm (-r option). You will also have to set up the user accounts,
for that you have a number of options:
a) command-line options (-u).
b) userdb config file.
c) a database table (PostgreSQL or MySQL). You will have to set keys with
turnadmin utility (see docs and wiki for turnadmin). You cannot use open passwords
in the database.
d) Redis key/value pair(s), if Redis is used. You key use either keys or
open passwords with Redis; see turndb/testredisdbsetup.sh file.
e) You also can use the TURN REST API. You will need shared secret(s) set
either through the command line option, or through the config file, or through
the database table or Redis key/value pairs.
2) Usually WebRTC uses fingerprinting (-f).
3) -v option may be nice to see the connected clients.
4) -X is needed if you are running your TURN server behind a NAT.
5) --min-port and --max-port may be needed if you want to limit the relay endpoints ports
number range.
===================================
TURN REST API
In WebRTC, the browser obtains the TURN connection information from the web
server. This information is a secure information - because it contains the
necessary TURN credentials. As these credentials are transmitted over the
public networks, we have a potential security breach.
If we have to transmit a valuable information over the public network,
then this information has to have a limited lifetime. Then the guy who
obtains this information without permission will be able to perform
only limited damage.
This is how the idea of TURN REST API - time-limited TURN credentials -
appeared. This security mechanism is based upon the long-term credentials
mechanism. The main idea of the REST API is that the web server provides
the credentials to the client, but those credentials can be used only
limited time by an application that has to create a TURN server connection.
The "classic" long-term credentials mechanism (LTCM) is described here:
http://tools.ietf.org/html/rfc5389#section-10.2
http://tools.ietf.org/html/rfc5389#section-15.4
For authentication, each user must know two things: the username and the
password. Optionally, the user must supply the ORIGIN value, so that the
server can figure out the realm to be used for the user. The nonce and
the realm values are supplied by the TURN server. But LTCM is not saying
anything about the nature and about the persistence
of the username and of the password; and this is used by the REST API.
In the TURN REST API, there is no persistent passwords for users. A user has
just the username. The password is always temporary, and it is generated by
the web server on-demand, when the user accesses the WebRTC page. And,
actually, a temporary one-time session only, username is provided to the user,
too.
The temporary user is generated as:
temporary-username="timestamp" + ":" + "username"
where username is the persistent user name, and the timestamp format is just
seconds sinse 1970 - the same value as time(NULL) function returns.
The temporary password is obtained as HMAC-SHA1 function over the temporary
username, with shared secret as the HMAC key, and then the result is encoded:
temporary-password = base64_encode(hmac-sha1(shared-secret, temporary-username))
Both the TURN server and the web server know the same shared secret. How the
shared secret is distributed among the involved entities is left to the WebRTC
deployment details - this is beyond the scope of the TURN REST API.
So, a timestamp is used for the temporary password calculation, and this
timestamp can be retrieved from the temporary username. This information
is valuable, but only temporary, while the timestamp is not expired. Without
knowledge of the shared secret, a new temporary password cannot be generated.
This is all formally described in Justin's Uberti TURN REST API document
that can be obtained following the link "TURN REST API" in the TURN Server
project's page http://code.google.com/p/coturn/.
Once the temporary username and password are obtained by the client (browser)
application, then the rest is just 'classic" long-term credentials mechanism.
For developers, we are going to describe it step-by-step below:
- a new TURN client sends a request command to the TURN server.
- TURN server sees that this is a new client and the message is not
authenticated.
- the TURN server generates a random nonce string, and return the
error 401 to the client, with nonce and realm included.
- the client sees the 401 error and it extracts two values from
the error response: the nonce and the realm.
- the client uses username, realm and password to produce a key:
key = MD5(username ":" realm ":" SASLprep(password))
(SASLprep is described here: http://tools.ietf.org/html/rfc4013)
- the client forms a new request, adds username, realm and nonce to the
request. Then, the client calculates and adds the integrity field to
the request. This is the trickiest part of the process, and it is
described in the end of section 15.4:
http://tools.ietf.org/html/rfc5389#section-15.4
- the client, optionally, adds the fingerprint field. This may be also
a tricky procedure, described in section 15.5 of the same document.
WebRTC usually uses fingerprinted TURN messages.
- the TURN server receives the request, reads the username.
- then the TURN server checks that the nonce and the realm in the request
are the valid ones.
- then the TURN server calculates the key.
- then the TURN server calculates the integrity field.
- then the TURN server compares the calculated integrity field with the
received one - they must be the same. If the integrity fields differ,
then the request is rejected.
In subsequent communications, the client may go with exactly the same
sequence, but for optimization usually the client, having already
information about realm and nonce, pre-calculates the integrity string
for each request, so that the 401 error response becomes unnecessary.
The TURN server may use "--stale-nonce" option for extra security: in
some time, the nonce expires and the client will obtain 438 error response
with the new nonce, and the client will have to start using the new nonce.
In subsequent communications, the sever and the client will always assume
the same password - the original password becomes the session parameter and
is never expiring. So the password is not changing while the session is valid
and unexpired. So, if the session is properly maintained, it may go forever,
even if the user password has been already changed (in the database). The
session simply is using the old password. Once the session got disconnected,
the client will have to use the new password to re-connect (if the password
has been changed).
An example when a new shared secret is generated every hour by the TURN server
box and then supplied to the web server, remotely, is provided in the script
examples/scripts/restapi/shared_secret_maintainer.pl .
A very important thing is that the nonce must be totally random and it must be
different for different clients and different sessions.
===================================
DATABASES
For the user database, the turnserver has the following options:
1) Users can be set in the command line, with multiple -u or --user options.
Obviously, only a few users can be set that way, and their credentials are fixed
for the turnserver process lifetime.
2) Users can be set in turnusers.conf flat file DB. The turnserver process periodically
re-reads this file, so the user accounts may be changed while the turnserver is running.
But still a relatively small (up to a hundred ?) number of users can be handled that way.
3) Users can be stored in PostgreSQL database, if the turnserver was compiled with PostgreSQL
support. Each time turnserver checks user credentials, it reads the database (asynchronously,
of course, so that the current flow of packets is not delayed in any way), so any change in the
database content is immediately visible by the turnserver. This is the way if you need the
best scalability. The schema for the database can be found in schema.sql file.
For long-term credentials, you have to set the "keys" for the users; the "keys" are generated
by the turnadmin utility. For the key generation, you need username, password and the realm.
All users in the database must use the same realm value; if down the road you will decide
to change the realm name, then you will have to re-generate all user keys (that can be done
in a batch script). If you are using short-term credentials, then you use open passwords
in the database; you will have to make sure that nobody can access the database outside of
the TURN server box. See the file turndb/testsqldbsetup.sql as an example.
4) The same is true for MySQL database. The same schema file is applicable.
The same considerations are applicable.
5) The same is true for the Redis database, but the Redis database has aa different schema -
it can be found (in the form of explanation) in schema.userdb.redis.
Also, in Redis you can store both "keys" and open passwords (for long term credentials) -
the "open password" option is less secure but more convenient for low-security environments.
For short-term credentials, you will use open passwords only. See the file
turndb/testredisdbsetup.sh as an example.
6) Of course, the turnserver can be used in non-secure mode, when users are allowed to establish
sessions anonymously. But in most cases (like WebRTC) that will not work.
For the status and statistics database, there are two choices:
1) The simplest choice is not to use it. Do not set --redis-statsdb option, and this functionality
will be simply ignored.
2) If you choose to use it, then set the --redis-statsdb option. This may be the same database
as in --redis-userdb option, or it may be a different database. You may want to use different
database for security or convenience reasons. Also, you can use different database management
systems for the user database and for the ststus and statistics database. For example, you can use
MySQL as the user database, and you can use redis for the statistics. Or you can use Redis for both.
So, we have 6 choices for the user management, and 2 choices for the statistics management. These
two are totally independent. So, you have overall 6*2=12 ways to handle persistent information,
choose any for your convenience.
You do not have to handle the database information "manually" - the turnadmin program can handle
everything for you. For PostgreSQL and MySQL you will just have to create an empty database
with schema.sql SQL script. With Redis, you do not have to do even that - just run turnadmin and
it will set the users for you (see the turnadmin manuals).
=================================
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.
=================================
DOCS
After installation, run the command:
$ man turnserver
or in the project root directory:
$ man -M man turnserver
to see the man page.
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/turnserver/html.
=================================
LOGS
When the TURN Server starts, it makes efforts to create a log file turn_<pid>.log
in the following directories:
* /var/log
* /log/
* /var/tmp
* /tmp
* current directory
If all efforts failed (due to the system permission settings) then all
log messages are sent only to the standard output of the process.
This behavior can be controlled by --log-file, --syslog and --no-stdout-log options.
=================================
TELNET CLI
The turnserver process provides a telnet CLI access as statistics and basic management
interface. By default, the turnserver starts a telnet CLI listener on IP 127.0.0.1 and
port 5766. That can be changed by the command-cline options of the turnserver process
(see --cli-ip and --cli-port options). The full list of telnet CLI commands is provided
in "help" command output in the telnet CLI.
=================================
CLUSTERS
TURN Server can be a part of the cluster installation. But, to support the "even port" functionality
(RTP/RTCP streams pairs) the client requests from a particular IP must be delivered to the same
TURN Server instance, so it requires some networking setup massaging for the cluster. The reason is that
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.
=================================
FILES
/etc/turnserver.conf
/etc/turnuserdb.conf
/usr/local/etc/turnserver.conf
/usr/local/etc/turnuserdb.conf
=================================
DIRECTORIES
/usr/local/share/turnserver
/usr/local/share/doc/turnserver
/usr/local/share/examples/turnserver
=================================
STANDARDS
obsolete STUN RFC 3489
new STUN RFC 5389
TURN RFC 5766
TURN-TCP extension RFC 6062
TURN IPv6 extension RFC 6156
STUN/TURN test vectors RFC 5769
STUN NAT behavior discovery RFC 5780
=================================
SEE ALSO
turnadmin, turnutils
======================================
WEB RESOURCES
project page:
http://code.google.com/p/coturn/
Wiki page:
http://code.google.com/p/coturn/wiki/Readme
forum:
https://groups.google.com/forum/?fromgroups=#!forum/turn-server-project-rfc5766-turn-server/
======================================
AUTHORS
Oleg Moskalenko <mom040267@gmail.com>
Gabor Kovesdan http://kovesdan.org/
Daniel Pocock http://danielpocock.com/
John Selbie (jselbie@gmail.com)
Lee Sylvester <lee@designrealm.co.uk>
Erik Johnston <erikj@openmarket.com>
Roman Lisagor <roman@demonware.net>
Vladimir Tsanev <tsachev@gmail.com>
Po-sheng Lin <personlin118@gmail.com>
Peter Dunkley <peter.dunkley@crocodilertc.net>
Mutsutoshi Yoshimoto <mutsutoshi.yoshimoto@mixi.co.jp>

329
README.turnutils Normal file
View File

@ -0,0 +1,329 @@
GENERAL INFORMATION
A set of turnutils_* programs provides some utility functionality to be used
for testing and for setting up the TURN server.
1. turnutils_uclient: emulates multiple UDP,TCP,TLS or DTLS clients.
(this program is provided for the testing purposes only !)
The compiled binary image of this program is located in bin/
sub-directory.
WARNING: the turnutils_uclient program is a primitive client application.
It does not implement the re-transmission pattern that is necessary for
a correct TURN client implementation. In TURN, the retransmission burden
is lying almost entirely on the client application. We provide the messaging
functionality in the client library, but the client must implement
the correct Networking IO processing in the client program code.
2. turnutils_peer: a simple stateless UDP-only "echo" server,
to be used as the final server in relay pattern ("peer"). For every incoming
UDP packet, it simply echoes it back.
(this program is provided for the testing purposes only !)
When the test clients are communicating in the client-to-client manner
(when the "turnutils_uclient" program is used with "-y" option) then the
turnutils_peer is not needed.
The compiled binary image of this program is located in bin/ subdirectory.
3. turnutils_stunclient: a simple STUN client example.
The compiled binary image of this program is located in bin/ subdirectory.
4. turnutils_rfc5769check: a utility that checks the correctness of the
STUN/TURN protocol implementation. This utility is used only for the compilation
check procedure, it is not copied to the installation destination.
In the "examples/scripts" subdirectory, you will find the examples of command lines to be used
to run the programs. The scripts are meant to be run from examples/ subdirectory, for example:
$ cd examples
$ ./scripts/secure_relay.sh
=====================================
NAME
turnutils_uclient - this client emulation application is supplied for the test purposes only.
SYNOPSIS
$ turnutils_uclient [-tTSvsyhcxg] [options] <TURN-Server-IP-address>
DESCRIPTION
It was designed to simulate multiple clients. It uses asynch IO API in
libevent to handle multiple clients. A client connects to the relay,
negotiates the session, and sends multiple (configured number) messages to the server (relay),
expecting the same number of replies. The length of the messages is configurable.
The message is an arbitrary octet stream, but it can be configured as a string.
The number of the messages to send is configurable.
Flags:
-t Use TCP 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.
-P Passive TCP (RFC6062 with active peer). Implies -T.
-S Secure SSL connection: SSL/TLS for TCP, DTLS for UDP.
-U Secure unencrypted connection (suite eNULL): SSL/TLS for TCP, DTLS for UDP.
-v Verbose.
-s Use "Send" method in TURN; by default, it uses TURN Channels.
-y Use client-to-client connections:
RTP/RTCP pair of channels to another RTP/RTCP pair of channels.
with this option the turnutils_peer application is not used,
as the allocated relay endpoints are talking to each other.
-h Hang on indefinitely after the last sent packet.
-c Do not create rtcp connections.
-x Request IPv6 relay address (RFC6156).
-X IPv4 relay address explicitly requested.
-g Set DONT_FRAGMENT parameter in TURN requests.
-A use short-term credentials mechanism for authentication.
By default, the program uses the long-term credentials mechanism
if authentication is required.
-D Do mandatory channel padding even for UDP (like pjnath).
-N do negative tests (some limited cases only).
-R do negative protocol tests.
-O DOS attack mode.
-H SHA256 digest function for message integrity calculation.
Without this option, by default, SHA1 is used.
-M Use TURN ICE Mobility.
-I Do not set permissions on TURN relay endpoints
(for testing the non-standard server relay functionality).
-G Generate extra requests (create permissions, channel bind).
Options with required values:
-l Message length (Default: 100 Bytes).
-i Certificate file (for secure connections only, optional).
-k Private key file (for secure connections only).
-E CA file for server certificate verification,
if the server certificate to be verified.
-p TURN Server port (Defaults: 3478 unsecure, 5349 secure).
-n Number of messages to send (Default: 5).
-d Local interface device (optional, Linux only).
-L Local IP address (optional).
-m Number of clients (Default: 1, 2 or 4, depending on options).
-e Peer address.
-r Peer port (Default: 3480).
-z Per-session packet interval in milliseconds (Default: 20).
-u STUN/TURN user name.
-w STUN/TURN user password.
-W TURN REST API authentication secret. Is not compatible with -A flag.
-C This is the timestamp/username separator symbol (character) in
TURN REST API. The default value is :.
-F Cipher suite for TLS/DTLS. Default value is DEFAULT.
See the examples in the "examples/scripts" directory.
======================================
NAME
turnutils_peer - a simple UDP-only echo backend server.
SYNOPSYS
$ turnutils_peer [-v] [options]
DESCRIPTION
This application is used for the test purposes only, as a peer for the turnutils_uclient application.
Options with required values:
-p Listening UDP port (Default: 3480).
-d Listening interface device (optional)
-L Listening address of turnutils_peer server. Multiple listening addresses can be used, IPv4 and IPv6.
If no listener address(es) defined, then it listens on all IPv4 and IPv6 addresses.
-v Verbose
========================================
NAME
turnutils_stunclient - a basic STUN client.
SYNOPSIS
$ turnutils_stunclient [options] <STUN-Server-IP-address>
DESCRIPTION
It sends a "new" STUN RFC 5389 request (over UDP) and shows the reply information.
Options with required values:
-p STUN server port (Default: 3478).
-L Local address to use (optional).
-f Force RFC 5780 processing.
The turnutils_stunclient program checks the results of the first request,
and if it finds that the STUN server supports RFC 5780
(the binding response reveals that) then the turnutils_stunclient makes a couple more
requests with different parameters, to demonstrate the NAT discovery capabilities.
This utility does not support the "old" "classic" STUN protocol (RFC 3489).
=====================================
NAME
turnutils_rfc5769check - a utility that tests the correctness of STUN protocol implementation.
SYNOPSIS
$ turnutils_rfc5769check
DESCRIPTION
turnutils_rfc5769check tests the correctness of STUN protocol implementation
against the test vectors predefined in RFC 5769 and prints the results of the
tests on the screen. This utility is used only for the compilation
check procedure, it is not copied to the installation destination.
Usage:
$ turnutils_rfc5769check
===================================
DOCS
After installation, run the command:
$ man turnutils
or in the project root directory:
$ man -M man turnutils
to see the man page.
=====================================
FILES
/etc/turnserver.conf
/etc/turnuserdb.conf
/usr/local/etc/turnserver.conf
/usr/local/etc/turnuserdb.conf
=================================
DIRECTORIES
/usr/local/share/turnserver
/usr/local/share/doc/turnserver
/usr/local/share/examples/turnserver
===================================
STANDARDS
new STUN RFC 5389
TURN RFC 5766
TURN-TCP extension RFC 6062
TURN IPv6 extension RFC 6156
STUN/TURN test vectors RFC 5769
STUN NAT behavior discovery RFC 5780
====================================
SEE ALSO
turnserver, turnadmin
======================================
WEB RESOURCES
project page:
http://code.google.com/p/coturn/
Wiki page:
http://code.google.com/p/coturn/wiki/Readme
forum:
https://groups.google.com/forum/?fromgroups=#!forum/turn-server-project-rfc5766-turn-server/
======================================
AUTHORS
Oleg Moskalenko <mom040267@gmail.com>
Gabor Kovesdan http://kovesdan.org/
Daniel Pocock http://danielpocock.com/
John Selbie (jselbie@gmail.com)
Lee Sylvester <lee@designrealm.co.uk>
Erik Johnston <erikj@openmarket.com>
Roman Lisagor <roman@demonware.net>
Vladimir Tsanev <tsachev@gmail.com>
Po-sheng Lin <personlin118@gmail.com>
Peter Dunkley <peter.dunkley@crocodilertc.net>
Mutsutoshi Yoshimoto <mutsutoshi.yoshimoto@mixi.co.jp>

101
STATUS Normal file
View File

@ -0,0 +1,101 @@
Currently implemented functionality:
1) RFC5389 (new STUN protocol) full server and client
implementations. We do not maintain strict compatibility
with the obsolete RFC 3489 "old STUN" protocol.
2) RFC5766 TURN protocol full server and client
implementations. We support file-based long term
user credentials, for now. We added experimental DTLS
protocol, too.
3) RFC6156 TURN IPv6 extension.
4) We support the following client-to-server
network transports for TURN messages:
a) UDP
b) TCP
c) TLS
d) DTLS
5) Performance tested.
6) Torture and stability tests.
7) Multiple *NIX platforms tested and supported.
8) TTL field handling implemented for all platforms, preferred behavior in RFC5766.
9) TOS (DiffServ and ECN) field handling (preferred behavior of RFC 5766) implemented,
for Linux. Other platforms support the alternative behavior of RFC 5766.
10) DF field alternative behavior of RFC 5766 implemented.
11) Bandwidth limitation per session implemented.
12) RFC 5769 test vectors implemented (where applicable).
13) RFC 5780 STUN extension: NAT behavior discovery.
14) C++ mapping implemented.
15) RFC 6062 TCP relaying implemented.
16) Users can be stored in PostgreSQL database.
17) Users can be stored in MySQL database.
18) TURN Server REST API implemented.
19) Short-term credentials mechanism implemented.
20) Simple load-balancing with ALTERNATE-SERVER implemented.
21) Redis database support added.
22) RFC3489 backward compatibility.
23) Multithreaded TCP relay processing (UDP relay has been
multithreaded from the beginning).
24) Networking engine 2.0 implemented, with more scalable approach
to the UDP sockets handling.
25) DOS attack prevention logic added to the server; DOS attack client
emulation implemented.
26) Linux UDP sockets workaround added to counter RFC 1122 behavior.
27) DTLS sockets re-implemented for better scalability and for Cygwin
compatibility.
28) A number of TLS/DTLS improvements added: multiple protocols support, certificate check option.
29) SHA256 support added (experimental).
30) UDP network engine optimized for the new Linux kernels (3.9+).
31) ICE Mobility draft implemented (experimental).
32) CLI implemented.
33) DH and EC TLS ciphers added.
34) HTTP "keep alive" request supported.
35) Optimized (for thousands and more sessions) timers implementation.
36) TCP network engine optimized for the new Linux kernels (3.9+).
37) telnet-based monitor implemented.
38) Package memory copy eliminated in traffic routing.
39) Congestion avoidance implemented, for all protocols.
40) Multi-tenant server implemented.
41) Coturn project forked from rfc5766-turn-server.
Things to be implemented in future (the development roadmap)
are described in the TODO file.

128
TODO Normal file
View File

@ -0,0 +1,128 @@
==================================================================
### I. PLATFORMS SUPPORT ###
==================================================================
1) Fedora official package (turnserver or coturn ? TBD).
2) MS Windows support.
Cygwin is supported. A "real" MS-Windows port would
involve a usable GUI.
==================================================================
### II. DOCS ###
==================================================================
1) User's manual.
2) Developer's manual.
==================================================================
### III. NETWORK ENGINE ###
==================================================================
1) Exclusive IP addresses for relay
==================================================================
### IV. PERFORMANCE OPTIMIZATION ###
==================================================================
1) A smarter load balancer has to be implemented.
The load balancer has to have a heartbeat channels with
the slave servers, currently it is only just a dumb
round-robin load distributor.
2) For a large enterprise, a user-space stack to be integrated.
An another socket abstraction to be implemented,
the one that uses the user-space TCP/IP stack with
zero memory copy. This is an ambitious goal that would
increase the system scaleability, significantly.
The stock TCP/IP stack in UNIX and in MS Windows do not
scale gracefully. We are trying to suppress those issues
in the TURN Server, by using an advanced synchronous
I/O technique, but still the underlying stock TCP/IP stack
is a limitation.
3) Multiple authentication threads.
==================================================================
### V. SECURITY ###
==================================================================
1) RADIUS integration ?
2) Watch new TURN security draft. oAuth integration.
==================================================================
### VI. STANDARDS SUPPORT ###
==================================================================
1) Follow the draft ICE endpoint mobility standard and add changes
when necessary:
https://ietf.org/doc/draft-wing-mmusic-ice-mobility/
2) For extra difficult NAT/FWs, consider implementing Websockets.
3) MS TURN, MS STUN extensions.
4) Bandwidth draft.
5) ALPN with TLS and DTLS.
6) Redirect draft.
==================================================================
### VII. MISC FEATURES ###
==================================================================
1) Locale support (?).
Currently we assume that all text data is 8-bits ASCII
encoded, like C locale. It would be nice to support localized
strings (both 8-bits and 2-bytes). But I am not sure
whether this is really important, given the essentially
backend nature of the TURN Server. The TURN server is so
deeply "hidden" in the network infrastructure that the
significant code complication may be unjustified.
2) HTTP or GUI status monitor and management.
For enterprise users, a management (configuration, status
and statistics) GUI has to be implemented. Currently, all
these features are available through the shell command
line, telnet client and through Redis command line.
3) Traffic recording (for selected allocations).
That would be a helpful feature for a large enterprise
(for testing and security purposes).
4) Ganglia monitoring.
==================================================================
### VIII. CODING STUFF ###
==================================================================
Nope
==================================================================

1063
configure vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,23 @@
-----BEGIN CERTIFICATE-----
MIIDzjCCArYCCQD3YHhln4EqhDANBgkqhkiG9w0BAQUFADCBpzELMAkGA1UEBhMC
VVMxCzAJBgNVBAgTAkNBMRUwEwYDVQQHEwxXYWxudXQgQ3JlZWsxKzApBgNVBAoT
IlJGQzU3NjYgVFVSTiBTZXJ2ZXIgcHVibGljIHByb2plY3QxFDASBgNVBAsTC2Rl
dmVsb3BtZW50MQ0wCwYDVQQDEwRPbGVnMSIwIAYJKoZIhvcNAQkBFhNtb20wNDAy
NjdAZ21haWwuY29tMCAXDTEyMTEyNzAwNDEwNVoYDzIxMTIxMTAzMDA0MTA1WjCB
pzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRUwEwYDVQQHEwxXYWxudXQgQ3Jl
ZWsxKzApBgNVBAoTIlJGQzU3NjYgVFVSTiBTZXJ2ZXIgcHVibGljIHByb2plY3Qx
FDASBgNVBAsTC2RldmVsb3BtZW50MQ0wCwYDVQQDEwRPbGVnMSIwIAYJKoZIhvcN
AQkBFhNtb20wNDAyNjdAZ21haWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEA3huHvPYyvNZBK91bP3O1dBdOj93YQ3812BTcRMjEYnvSyyEosxFd
dEnILgDiFK//pFnDtwm7FxOCtVwRQ0+8qGTH4vH0EIpKTBsaafKH3L9CYe40pwcm
BJHvclOa4vl2Ghi09+M0UEHdokkM77K9rpXx7aZILoICkqnoAuBe0TY8D5PBXinM
gtk7HlrvANxSmPHAAaGQ5t/+jfTWVH1UYCpogTgCKYPbNi+joKu6oEz+qRKAqDYd
FY6/Qpiv7reYiNiVhM7HGNY27FkKDJDBhsmZRmtTIEdYFfcWPZvv69L7Rf1skOXF
Vm5/to3HArJJF+lz6YGj0C3pE6dZt6sUmQIDAQABMA0GCSqGSIb3DQEBBQUAA4IB
AQAhXgGdXXf0dMPdkfl4jv4dqFNSmax6wmeNc+oJC9qIFVDLsdAaAWXZ+pZHYIMR
UN8mQobsIZdfPQ0gs8CgUwrKziAjA92y2Q/I7vsg83qRLhysGC5etYMD/wlySDDS
AJKraevDPTEdmfNstCblubNG2PIeqV1isWtPMqB2dMsCeyzJXVyfD0QcABzFv4Fs
MMy7JI7MsctNh1tjV/0TsddDMeMLs22rix5fS8MZ6uunFzIuJ0MshFNehXFuvz0B
uNmn0k7djUm3h+2Avs3YGCo/8GtqHapc/lva/9gT+iEW0e7i0Ru5Jhar66VMzJqv
+wEhQafC77d3vWHtXQU8dYmM
-----END CERTIFICATE-----

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA3huHvPYyvNZBK91bP3O1dBdOj93YQ3812BTcRMjEYnvSyyEo
sxFddEnILgDiFK//pFnDtwm7FxOCtVwRQ0+8qGTH4vH0EIpKTBsaafKH3L9CYe40
pwcmBJHvclOa4vl2Ghi09+M0UEHdokkM77K9rpXx7aZILoICkqnoAuBe0TY8D5PB
XinMgtk7HlrvANxSmPHAAaGQ5t/+jfTWVH1UYCpogTgCKYPbNi+joKu6oEz+qRKA
qDYdFY6/Qpiv7reYiNiVhM7HGNY27FkKDJDBhsmZRmtTIEdYFfcWPZvv69L7Rf1s
kOXFVm5/to3HArJJF+lz6YGj0C3pE6dZt6sUmQIDAQABAoIBAH5ITN8FZEe10gws
qUrkcRD2h3aI/gMyetzGz45UUERmfq17xvY5M1eA884kNmbowoMhfoO9hqBSOYkA
Ndh9p5he5L+GLeyRlDi9WEFQ4iqCnC2uEEW/bMBAcVIhcvkGOT4ROiOPDRlsuaUh
v7cxe2OeYZVra7L1vJzC+eVYyNBN5CgK8w08MPEkupQS9+Jvr0QWCikRz187cG45
EiDMrBKyJNE9lY6u4P8gJ+/NgaASWP/D3kbsjiQ2OwSGLrwDAvWC7Bx2GK3/0goA
btp7YGaWvp+mE5V91cOW+PfweC5Do4MjOr4ToNkczW0AxKE5o94yo56h+II5bX6N
z65VvtkCgYEA/Sq/3S2yup/Oodzj003KG4skWYFrj7KXeXgm7RZcpNwkd8JaFXJ/
Cwl7/3bkRv6RHLmXX/2hcNWlxq3u6Efs1EjtycdArU68kO01vLdExJYIzHKmHikV
n+T4hukxGDzObxn3lH1KcOodh/x572Uufn79dewoZCPzH8t/jiMOWGcCgYEA4JfN
66Kq/oDookqenM9Ij5l6zeeNwzMjIlkU2eG0DAH0KdsBN/hTGGGRQVBk03YREQmK
crEhGAZxzfrX5fK11UVG3C2pqAtrVe6FuD32vFUpP1MO0ftSA889NoEwGdNZV4pV
Mk0+6xVCNOatj2inMXlQq5s68WfCzkiWD7uLCv8CgYBcwuYsF4tuYBGpMzNzAAS2
1OPLu+T6cPiZdFHm+xOVAGiITPkO9LXiCGabsydvb+UhvkrdzCP0IQQt6RsplvkK
y3H9RfnHxprHC3NuI0SaN1Mf/j4pvOoEfTQm0pi/hcAp6zzQ9ptpBg8t/W98LPm9
NbCPHamrD5UMqFajcOrXrwKBgD8D2M8IcRm/aYY/kYlFz4Ia+g3Trj7alj0I6YTI
gw/rbGph/FGL5ySsG2lL+T4rnlY9aw8LC9IF3OCCRRlLpCEWsu8MENIJgjA2IGa1
XAkzi8MstrfL4BMZjn9AeBKG7kZVldnrOoATEuRs5L2cC20iMLQ1dbBOAKaITzJS
2IxZAoGBAKqwr/uennxJrnMtpjLBgcphoU3aXJZvzzDqlOaqzJp6Xmbese4sDEe0
hvVHreigDzOnGnqL/vSjTDWaLqS/O1iE7p+UrGIkZj/Zl6Jk54OX6AHmWE2LhdlU
FYgIQKX7fuocpF1Dpe7xEeVwvdp+UqbDzHQg1CWGe1cBPYDYIkSH
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDsDCCApgCCQCmgrJCiQlGOTANBgkqhkiG9w0BAQUFADCBmDELMAkGA1UEBhMC
VVMxCzAJBgNVBAgTAkNBMRUwEwYDVQQHEwxXYWxudXQgQ3JlZWsxHDAaBgNVBAoT
E1RVUk4gU2VydmVyIHByb2plY3QxFDASBgNVBAsTC0RldmVsb3BtZW50MQ0wCwYD
VQQDEwRPbGVnMSIwIAYJKoZIhvcNAQkBFhNtb20wNDAyNjdAZ21haWwuY29tMCAX
DTEyMTEyNTA4MjAxNloYDzIxMTIxMTAxMDgyMDE2WjCBmDELMAkGA1UEBhMCVVMx
CzAJBgNVBAgTAkNBMRUwEwYDVQQHEwxXYWxudXQgQ3JlZWsxHDAaBgNVBAoTE1RV
Uk4gU2VydmVyIHByb2plY3QxFDASBgNVBAsTC0RldmVsb3BtZW50MQ0wCwYDVQQD
EwRPbGVnMSIwIAYJKoZIhvcNAQkBFhNtb20wNDAyNjdAZ21haWwuY29tMIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv6bYkERhZ43RjW4EuqCaTq5g+D+l
JI/GwlVzdzQ3+F4clMQDR1kp1nX+9AvwjCXz3AYwY1H9CqjmjGM4R9uNJJseK/aJ
d2DUFADkF+7I674XwX8U2Fy5on9jqWq3jdbb8eg/awcTBdrNLWNPquwfS2KVdooj
9yPkqnO0c3ko1/OzIQCcs09O3l/MPt+aOsHk3B9l79ZRs3zWkylI+we0Fnc+7tZE
psCztA+KCCoiJf7NenOvVhdKg7D1AXuzJ/P/Euvc3+CIiS9HI4pWLopY1k+HydLe
IcopqSbg9CRIKe1HOL8YTvCm2ZoTqgijwWUlGtwEDf2xxUQX/TLYiW8JFQIDAQAB
MA0GCSqGSIb3DQEBBQUAA4IBAQATbrBOLV4e8Qmsby9+srxXsdbNc60PmDZ4WiZ1
IElfWmzM7wGXm9sJg1PX/7T24R1tbwZGLIhZnkhecG372GChULZJ9Pdjh0Ab2nK5
LRKHXTpjp/xOJvx0JMCIIyRnGZT1nABPOk8uEjNW8PaU6yhQ4f5nKaSOgYGRCln6
dcy5vylCsyD9Q7GXs0KOC38XD+Ycv6VLX4zKJ2Yum50Wt643nLjG9RlGT3FXWJ1K
HUbPC5TO6bcYLdiTjaYr+X8xC/x6h/Ngdo/16w7fRmQQ4uS+TVXrg8ITmI71KX/I
m7C9jbsubwzrhW84oZXYf+o/0ATtEAhiVLnHifKCCYikqfVj
-----END CERTIFICATE-----

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAv6bYkERhZ43RjW4EuqCaTq5g+D+lJI/GwlVzdzQ3+F4clMQD
R1kp1nX+9AvwjCXz3AYwY1H9CqjmjGM4R9uNJJseK/aJd2DUFADkF+7I674XwX8U
2Fy5on9jqWq3jdbb8eg/awcTBdrNLWNPquwfS2KVdooj9yPkqnO0c3ko1/OzIQCc
s09O3l/MPt+aOsHk3B9l79ZRs3zWkylI+we0Fnc+7tZEpsCztA+KCCoiJf7NenOv
VhdKg7D1AXuzJ/P/Euvc3+CIiS9HI4pWLopY1k+HydLeIcopqSbg9CRIKe1HOL8Y
TvCm2ZoTqgijwWUlGtwEDf2xxUQX/TLYiW8JFQIDAQABAoIBADUPHCXUyKLCwKFH
NEf27sGZxX71H+NfaseioLT/3/8DDyagncfDB7I4OL2YEKC8YScpD3xv1n59BFcZ
oRtDzW+1AkVpm+VRCWYAWSXHFhkuJ6WKaVr9UOeMHStqQCcktP/kLKqU6s9UJDnM
pOHNPVzBjl+jHxHs/gGyxuKxSH2Anwkrzpiv5j0obKFnw3QtAqeZRs1NlvPtYt2S
eihZWr8r8LqylPk9ga9MYmO79Yr+EPVaqd6bmz4MpZJ4/7LEjx03Q6azdMCPhFNY
cYzPIDZFEj81Zj/tqA2MU/uTTUUrcXint4dHRJs34m5N68PV1Y1XhhH6FG0+X711
ZymudoECgYEA/ChS5zmmOoLoaq2441+PzQbDP45qR6+G4slHwC8RDZhsYw0hQnp9
n44Qagpt74J4FjxT20BdE714DZP32IqagUwatWRQ+z3UoGafkJSNc5JSEogwZ65C
nC8RI1pPHLEvE8IzBJiqUA1kbMOMfTYW694wdN9JVZang05/AXaJzm8CgYEAwpJ8
nJRR9JFweHRrRgnrVk0Qi+ABbN9T/nhPXYab2vjBfeBOTA1Mob0M3zMJDCnL2i+D
K1GzE6WaYHElr45j2Wfphd/rRTk74WR4BaPpTCGaAhBQNn0ufqUkKsCPEAlTU+nG
iyXP4OvdMPjEBckjbKm/mlX7m0njSHAY6SWNorsCgYEAi8Yubk3efwChpMC3hBIs
vBHLmSdwclwyAPRh+X4djdO4AQ/+J8OObytond86IVHJD0pRkW+UKKUWLzCeakIq
cxGknHgHC72yZ1d7i8FMx4uMQwmLC23lLn5ImbgtslHlLqavcRTPE6DY0hFzhtS8
z/JSGfbLx83C/V49uKnkqbECgYA6h1oYt70XdpCAi3ShcuZp5XCuwslq+JsJlyM4
nP9RFTcPKGQlGHMOzBGNKor0L7Z0gYpRg5f8tvoDPMX7UzfR9CIY9UyOXDMZD+HS
wIWzMwBi0olueqV7zy1b9uSSDFwWh+IDhXJM1GaLDqnYm7KeQ0mxoV+4TLej2KSF
rZg3dQKBgQCVrVxFV8jHBsRsH5PzMx6pUSAollmuyte9mGU1MIE7EZf+LEQIAjGZ
9jvtAILYVJXwVZv1/zNxldUfBNuWc95ft+Gg7FEN0p0uLpdYNXQUcXuJaJ9tJ1td
ZfvRcrUXdFNKYt9/yaGeHVaIQfp4W1faZD7OnII7EOVkUKyv/qNGAA==
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,589 @@
# Coturn TURN SERVER configuration file
#
# Boolean values note: where boolean value is supposed to be used,
# you can use '0', 'off', 'no', 'false', 'f' as 'false,
# and you can use '1', 'on', 'yes', 'true', 't' as 'true'
# If the value is missed, then it means 'true'.
#
# Listener interface device (optional, Linux only).
# NOT RECOMMENDED.
#
#listening-device=eth0
# TURN listener port for UDP and TCP (Default: 3478).
# 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
# "automatically" recognizes the type of traffic. Actually, two listening
# endpoints (the "plain" one and the "tls" one) are equivalent in terms of
# functionality; but we keep both endpoints to satisfy the RFC 5766 specs.
# For secure TCP connections, we currently support SSL version 3 and
# TLS version 1.0, 1.1 and 1.2. SSL2 "encapculation mode" is also supported.
# For secure UDP connections, we support DTLS version 1.
#
#tls-listening-port=5349
# Alternative listening port for UDP and TCP listeners;
# 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
# 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".
#
#alt-tls-listening-port=0
# 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,
# then all IPv4 and IPv6 system IPs will be used for listening.
#
#listening-ip=172.17.19.101
#listening-ip=10.207.21.238
#listening-ip=2607:f0d0:1002:51::4
# Auxiliary STUN/TURN server listening endpoint.
# Aux servers have almost full TURN and STUN functionality.
# The (minor) limitations are:
#
# 1) Auxiliary servers do not have alternative ports and
# 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
# to client requests.
#
#aux-server=172.17.19.110:33478
#aux-server=[2607:f0d0:1002:51::4]:33478
# (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
# functionality.
#
#udp-self-balance
# Relay interface device for relay sockets (optional, Linux only).
# NOT RECOMMENDED.
#
#relay-device=eth1
# 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
# 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).
#
#relay-ip=172.17.19.105
#relay-ip=2607:f0d0:1002:51::5
# For Amazon EC2 users:
#
# TURN Server public/private address mapping, if the server is behind NAT.
# In that situation, if a -X is used in form "-X <ip>" then that ip will be reported
# as relay IP address of all allocations. This scenario works only in a simple case
# when one single relay address is be used, and no RFC5780 functionality is required.
# That single relay address must be mapped by NAT to the 'external' IP.
# The "external-ip" value, if not empty, is returned in XOR-RELAYED-ADDRESS field.
# For that 'external' IP, NAT must forward ports directly (relayed port 12345
# must be always mapped to the same 'external' port 12345).
#
# In more complex case when more than one IP address is involved,
# that option must be used several times, each entry must
# have form "-X <public-ip/private-ip>", 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
# is behind A NAT.
#
# By default, this value is empty, and no address mapping is used.
#
#external-ip=60.70.80.91
#
#OR:
#
#external-ip=60.70.80.91/172.17.19.101
#external-ip=60.70.80.92/172.17.19.102
# Number of relay threads to handle the established connections
# (in addition to authentication thread and the listener thread).
# If 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).
#
# 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 1 (one) value is set.
#
#relay-threads=0
# Lower and upper bounds of the UDP relay endpoints:
# (default values are 49152 and 65535)
#
#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 any normal circumstances.
#
#Verbose
# Uncomment to use fingerprints in the TURN messages.
# By default the fingerprints are off.
#
#fingerprint
# Uncomment to use long-term credential mechanism.
# By default no credentials mechanism is used (any user allowed).
# This option can be used with either flat file user database or
# PostgreSQL DB or MySQL DB or Redis DB for user keys storage.
#
#lt-cred-mech
# Uncomment to use short-term credential mechanism.
# By default no credentials mechanism is used (any user allowed).
# For short-term credential mechanism you have to use PostgreSQL or
# MySQL or Redis database for user password storage.
#
#st-cred-mech
# This option is opposite to lt-cred-mech or st-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,
# in this file or in command line or in usersdb file, then
# lt-cred-mech is default.
#
#no-auth
# TURN REST API flag.
# Flag that sets a special authorization option that is based upon authentication secret.
# This feature can be used with the long-term authentication mechanism, only.
# This feature purpose is to support "TURN Server REST API", see
# "TURN REST API" link in the project's page
# http://code.google.com/p/coturn/.
#
# This option is used with timestamp:
#
# usercombo -> "timestamp:userid"
# turn user -> usercombo
# turn password -> base64(hmac(secret key, usercombo))
#
# This allows TURN credentials to be accounted for a specific user id.
# If you don't have a suitable id, the timestamp alone can be used.
# This option is just turning on secret-based authentication.
# The actual value of the secret is defined either by option static-auth-secret,
# or can be found in the turn_secret table in the database (see below).
#
#use-auth-secret
# '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 turn_secret table
# in user database (if present). The database-stored value can be changed on-the-fly
# by a separate program, so this is why that other mode is 'dynamic'.
#
#static-auth-secret
# 'Static' user accounts for long term credentials mechanism, only.
# This option cannot be used with TURN REST API or with short-term credentials
# mechanism.
# 'Static' user accounts are NOT dynamically checked by the turnserver process,
# so that they can NOT be changed while the turnserver is running.
#
#user=username1:key1
#user=username2:key2
# OR:
#user=username1:password1
#user=username2:password2
#
# Keys must be generated by turnadmin utility. The key value depends
# on user name, realm, and password:
#
# Example:
# $ turnadmin -k -u ninefingers -r north.gov -p youhavetoberealistic
# Output: 0xbc807ee29df3c9ffa736523fb2c4e8ee
# ('0x' in the beginning of the key is what differentiates the key from
# 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
#
# 'Dynamic' user accounts database file name.
# Only users for long-term mechanism can be stored in a flat file,
# short-term mechanism will not work with option, the short-term
# mechanism required PostgreSQL or MySQL or Redis database.
# 'Dynamic' long-term user accounts are dynamically checked by the turnserver process,
# so that they can be changed while the turnserver is running.
#
# Default file name is turnuserdb.conf.
#
#userdb=/usr/local/etc/turnuserdb.conf
# PostgreSQL database connection string in the case that we are using PostgreSQL
# as the user database.
# This database can be used for long-term and short-term credential mechanisms
# and it can store the secret value for secret-based timed authentication in TURN RESP API.
# See http://www.postgresql.org/docs/8.4/static/libpq-connect.html for 8.x PostgreSQL
# 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.
#
#psql-userdb="host=<host> dbname=<database-name> user=<database-user> password=<database-user-password> connect_timeout=30"
# MySQL database connection string in the case that we are using MySQL
# as the user database.
# This database can be used for long-term and short-term credential mechanisms
# and it can store the secret value for secret-based timed authentication in TURN RESP API.
# Use string format as below (space separated parameters, all optional):
#
#mysql-userdb="host=<host> dbname=<database-name> user=<database-user> password=<database-user-password> port=<port> connect_timeout=<seconds>"
# Redis database connection string in the case that we are using Redis
# as the user database.
# This database can be used for long-term and short-term credential mechanisms
# and it can store the secret value for secret-based timed authentication in TURN RESP API.
# Use string format as below (space separated parameters, all optional):
#
#redis-userdb="ip=<ip-address> dbname=<database-number> password=<database-user-password> port=<port> connect_timeout=<seconds>"
# 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.
# Use string format as below (space separated parameters, all optional):
#
#redis-statsdb="ip=<ip-address> dbname=<database-number> password=<database-user-password> port=<port> connect_timeout=<seconds>"
# The default realm to be used for the users when no explicit
# origin/realm relationship was 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
# mechanism or with TURN REST API.
#
#realm=mycompany.org
# Per-user allocation quota.
# default value is 0 (no quota, unlimited number of sessions per user).
# This option can also be set through the database, for a particular realm.
#
#user-quota=0
# Total allocation quota.
# default value is 0 (no quota).
# This option can also be set through the database, for a particular realm.
#
#total-quota=0
# Max bytes-per-second bandwidth a TURN session is allowed to handle
# (input and output network streams are treated separately). Anything above
# that limit will be dropped or temporary suppressed (within
# the available buffer limits).
# This option can also be set through the database, for a particular realm.
#
#max-bps=0
# Uncomment if no UDP client listener is desired.
# By default UDP client listener is always started.
#
#no-udp
# Uncomment if no TCP client listener is desired.
# By default TCP client listener is always started.
#
#no-tcp
# Uncomment if no TLS client listener is desired.
# By default TLS client listener is always started.
#
#no-tls
# Uncomment if no DTLS client listener is desired.
# By default DTLS client listener is always started.
#
#no-dtls
# Uncomment if no UDP relay endpoints are allowed.
# By default UDP relay endpoints are enabled (like in RFC 5766).
#
#no-udp-relay
# Uncomment if no TCP relay endpoints are allowed.
# By default TCP relay endpoints are enabled (like in RFC 6062).
#
#no-tcp-relay
# Uncomment if extra security is desired,
# with nonce value having limited lifetime (600 secs).
# By default, the nonce value is unique for a session,
# but it has unlimited lifetime. With this option,
# the nonce lifetime is limited to 600 seconds, after that
# the client will get 438 error and will have to re-authenticate itself.
#
#stale-nonce
# Certificate file.
# Use an absolute path or path relative to the
# configuration file.
#
#cert=/usr/local/etc/turn_server_cert.pem
# Private key file.
# Use an absolute path or path relative to the
# configuration file.
# Use PEM file format.
#
#pkey=/usr/local/etc/turn_server_pkey.pem
# Private key file password, if it is in encoded format.
# This option has no default value.
#
#pkey-pwd=...
# Allowed OpenSSL cipher list for TLS/DTLS connections.
# Default value is "DEFAULT".
#
#cipher-list="DEFAULT"
# CA file in OpenSSL format.
# Forces TURN server to verify the client SSL certificates.
# By default it is not set: there is no default value and the client
# certificate is not checked.
#
# 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.
#
#ec-curve-name=prime256v1
# Use 566 bits predefined DH TLS key. Default size of the key is 1066.
#
#dh566
# Use 2066 bits predefined DH TLS key. Default size of the key is 1066.
#
#dh2066
# 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.
#
#dh-file=<DH-PEM-file-name>
# Flag to prevent stdout log messages.
# By default, all log messages are going to both stdout and to
# the configured log file. With this option everything will be
# going 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
# /var/log, /var/tmp, /tmp and current directories directories
# (which open operation succeeds first that file will be used).
# With this option you can set the definite log file name.
# 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).
#
#log-file=/var/tmp/turn.log
# Option to redirect all log output into system log (syslog).
#
#syslog
# This flag means that no log file rollover will be used, and the log file
# name will be constructed as-is, without PID and date appendage.
#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 form of
# <ip>[:<port>]. 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 ALTERNATE-SERVER functionality description.
# The client must use the obtained value for subsequent TURN communications.
# If more than one --alternate-server options are 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
# 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 .
# 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 we 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:
#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
# <ip>:<port>. 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:
#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
# Option to suppress TURN functionality, only STUN requests will be processed.
# Run as STUN server only, all TURN requests will be ignored.
# By default, this option is NOT set.
#
#stun-only
# Option to suppress STUN functionality, only TURN requests will be processed.
# Run as TURN server only, all STUN requests will be ignored.
# By default, this option is NOT set.
#
#no-stun
# This is the timestamp/username separator symbol (character) in TURN REST API.
# The default value is ':'.
# rest-api-separator=:
# Flag that can be used to disallow peers on the loopback addresses (127.x.x.x and ::1).
# This is an extra security measure.
#
#no-loopback-peers
# Flag that can be used to disallow peers on well-known broadcast addresses (224.0.0.0 and above, and FFXX:*).
# This is an extra security measure.
#
#no-multicast-peers
# 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
# 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
# internet (e.g. when the turn server is sitting behind a NAT)
#
# Examples:
# denied-peer-ip=83.166.64.0-83.166.95.255
# allowed-peer-ip=83.166.68.45
# 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 .
#
#pidfile="/var/run/turnserver.pid"
# Require authentication of the STUN Binding request.
# By default, the clients are allowed anonymous access to the STUN Binding functionality.
#
#secure-stun
# Require SHA256 digest function to be used for the message integrity.
# By default, the server uses SHA1 (as per TURN standard specs).
# With this option, the server
# always requires the stronger SHA256 function. The client application
# must support SHA256 hash function if this option is used. If the server obtains
# a message from the client with a weaker (SHA1) hash function then the
# server returns error code 426.
#
#sha256
# Mobility with ICE (MICE) specs support.
#
#mobility
# 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.
#
#proc-user=<user-name>
# Group name to run the process. After the initialization, the turnserver process
# will make an attempt to change the current group ID to that group.
#
#proc-group=<group-name>
# Turn OFF the CLI support.
# By default it is always ON.
# See also options cli-ip and cli-port.
#
#no-cli
#Local system IP address to be used for CLI server endpoint. Default value
# is 127.0.0.1.
#
#cli-ip=127.0.0.1
# CLI server port. Default is 5766.
#
#cli-port=5766
# CLI access password. Default is empty (no password).
#
#cli-password=logen
# Server relay. NON-STANDARD AND DANGEROUS OPTION.
# Only for those applications when we want to run
# server applications on the relay endpoints.
# This option eliminates the IP permissions check on
# the packets incoming to the relay endpoints.
#
#server-relay
# Maximum number of output sessions in ps CLI command.
# This value can be changed on-the-fly in CLI. The default value is 256.
#
#cli-max-output-sessions
# Set network engine type for the process (for internal purposes).
#
#ne=[1|2|3]
# Do not allow an SSL/TLS version of protocol
#
#no-sslv2
#no-sslv3
#no-tlsv1
#no-tlsv1_1
#no-tlsv1_2

View File

@ -0,0 +1,23 @@
#This file can be used as user accounts storage for long-term credentials mechanism.
#
#username1:key1
#username2:key2
# OR:
#username1:password1
#username2:password2
#
# Keys must be generated by turnadmin utility. The key value depends
# on user name, realm, and password:
#
# Example:
# $ turnadmin -k -u ninefingers -r north.gov -p youhavetoberealistic
# Output: 0xbc807ee29df3c9ffa736523fb2c4e8ee
# ('0x' in the beginning of the key is what differentiates the key from
# password. If it has 0x then it is a key, otherwise it is a password).
#
# The corresponding user account entry in the userdb file will be:
#
#ninefingers:0xbc807ee29df3c9ffa736523fb2c4e8ee
# Or, equivalently (less secure):
#ninefingers:youhavetoberealistic
#

View File

@ -0,0 +1,35 @@
#!/bin/sh
#
# This is an example of a script for DOS attack emulation
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/
while [ 0 ] ; do
PATH=examples/bin/:../bin/:bin/:${PATH} turnutils_uclient -O -D -G -n 1 -m 12 -e 127.0.0.1 -X -g $@ ::1 &
PATH=examples/bin/:../bin/:bin/:${PATH} turnutils_uclient -O -G -n 1 -m 12 -y -s $@ 127.0.0.1 &
PATH=examples/bin/:../bin:bin/:${PATH} turnutils_uclient -O -G -t -n 1 -m 12 -e 127.0.0.1 -X -g $@ ::1 &
PATH=examples/bin/:../bin:bin/:${PATH} turnutils_uclient -O -G -T -n 1 -m 12 -y -s $@ 127.0.0.1 &
sleep 1
type killall >>/dev/null 2>>/dev/null
ER=$?
if [ ${ER} -eq 0 ] ; then
killall turnutils_uclient >>/dev/null 2>>/dev/null
else
type pkill >>/dev/null 2>>/dev/null
ER=$?
if [ ${ER} -eq 0 ] ; then
pkill turnutils_u >>/dev/null 2>>/dev/null
fi
fi
done

30
examples/scripts/basic/relay.sh Executable file
View File

@ -0,0 +1,30 @@
#!/bin/sh
#
# This is an example how to start a TURN Server in
# non-secure mode (when authentication is not used).
# We start here a TURN Server listening on IPv4 address
# 127.0.0.1 and on IPv6 address ::1. We use 127.0.0.1 as
# IPv4 relay address, and we use ::1 as IPv6 relay address.
# Other options:
# set bandwidth limit on client session 3000000 bytes per second (--max-bps)
# use fingerprints (-f)
# use 3 relay threads (-m 3)
# use min UDP relay port 32355 and max UDP relay port 65535
# --no-tls and --no-dtls mean that we are not trying to
# --no-auth means that no authentication to be used,
# allow anonymous users.
# start TLS and DTLS services.
# Other parameters (config file name, etc) are default.
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
PATH="bin:../bin:../../bin:${PATH}" turnserver -v --syslog -L 127.0.0.1 -L ::1 -E 127.0.0.1 -E ::1 --max-bps=3000000 -f -m 3 --min-port=32355 --max-port=65535 --no-tls --no-dtls --no-auth $@

View File

@ -0,0 +1,27 @@
#!/bin/sh
#
# This is an example of a script to run a "unsecure" TURN TCP client.
# Options:
# 1) -t is present, it means that TCP networking is used.
# 5) -n 1000 means 1000 messages per single emulated client. Messages
# are sent with interval of 20 milliseconds, to emulate an RTP stream.
# 6) -m 10 means that 10 clients are emulated.
# 7) -l 170 means that the payload size of the packets is 170 bytes
# (like average audio RTP packet).
# 8) -e 127.0.0.1 means that the clients will use peer address 127.0.0.1.
# 9) -g means "set DONT_FRAGMENT parameter in TURN requests".
# 10) -s option is absent - it means that the client will be using
# the "channel" mechanism for data.
# 11) -X means that IPv4 relay address is requested.
# 12) ::1 (the last parameter) is the TURN Server IP address. We use IPv6 here
# to illustrate how the TURN Server convert the traffic from IPv6 to IPv4 and back.
#
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/
PATH=examples/bin/:../bin:bin/:${PATH} turnutils_uclient -t -n 1000 -m 10 -l 3037 -e 127.0.0.1 -g -X $@ ::1

View File

@ -0,0 +1,25 @@
#!/bin/sh
#
# This is an example of a script to run a "unsecure" TURN TCP client
# with TCP relay endpoints (RFC 6062).
# Options:
# 1) -T is present, it means that TCP networking is used with TCP relay endpoints.
# 5) -n 1000 means 1000 messages per single emulated client. Messages
# are sent with interval of 20 milliseconds, to emulate an RTP stream.
# 6) -m 10 means that 10 clients are emulated.
# 7) -l 170 means that the payload size of the packets is 170 bytes
# (like average audio RTP packet).
# 8) -y means that the clients will connect to the 'neighbor' clients, no peer app will be used.
# 9) -g means "set DONT_FRAGMENT parameter in TURN requests".
# 10) ::1 (the last parameter) is the TURN Server IP address. We use IPv6 here
# to illustrate how the TURN Server convert the traffic from IPv6 to IPv4 and back.
#
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/
PATH=examples/bin/:../bin:bin/:${PATH} turnutils_uclient -T -n 1000 -m 10 -l 170 -y -g $@ ::1

View File

@ -0,0 +1,29 @@
#!/bin/sh
#
# This is an example of a script to run a "unsecure" TURN UDP client,
# in client-to-client fashion (when client talks to another client
# through their corresponding allocated relayed endpoints).
# Options:
# 1) -t is absent, it means that UDP networking is used.
# 5) -n 1000 means 1000 messages per single emulated client. Messages
# are sent with interval of 20 milliseconds, to emulate an RTP stream.
# 6) -m 10 means that 10 clients are emulated.
# 7) -y means "client to client" communication pattern.
# the client calculates the peer address
# (which is the allocated relayed endpoint of the next client in array of clients).
# 8) -l 170 means that the payload size of the packets is 170 bytes
# like average audio RTP packet).
# 9) -s option is absent - it means that the client will be using
# the "channel" mechanism for data.
# 10) 127.0.0.1 (the last parameter) is the TURN Server IP address.
# 11) -z 5 means that we want 5 ms interval between the packets (per each session).
#
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/
PATH=examples/bin/:../bin/:bin/:${PATH} turnutils_uclient -n 1000 -m 10 -y -l 170 -z 15 $@ 127.0.0.1

View File

@ -0,0 +1,28 @@
#!/bin/sh
#
# This is an example of a script to run a "unsecure" TURN UDP client.
# Options:
# 0) -D means "mandatory padding", like pjnath does;
# 1) -t is absent, it means that UDP networking is used.
# 5) -n 1000 means 1000 messages per single emulated client. Messages
# are sent with interval of 20 milliseconds, to emulate an RTP stream.
# 6) -m 10 means that 10 clients are emulated.
# 7) -l 171 means that the payload size of the packets is 171 bytes
# (like average audio RTP packet).
# 8) -e 127.0.0.1 means that the clients will use peer address 127.0.0.1.
# 9) -g means "set DONT_FRAGMENT parameter in TURN requests".
# 10) -s option is absent - it means that the client will be using
# the "channel" mechanism for data.
# 11) -X means that IPv4 relay address is requested.
# 12) 127.0.0.1 (the last parameter) is the TURN Server IP address. We use IPv4 here
# to illustrate how the TURN Server convert the traffic from IPv6 to IPv4 and back.
#
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/
PATH=examples/bin/:../bin/:bin/:${PATH} turnutils_uclient -D -n 1000 -m 10 -l 171 -e 127.0.0.1 -g -X $@ 127.0.0.1

View File

@ -0,0 +1,38 @@
#!/bin/sh
#
# This is an example of a MASTER TURN server that distributes
# the load among several "slave" TURN servers.
#
# The TURN Server is started in
# secure mode (when authentication is used) - see option -a
# that means "use long-term credential mechanism".
#
# We start here a TURN Server listening on IPv4 address
# 127.0.0.1. We use 127.0.0.1 as the relay address, too.
#
# Other options:
#
# 1) set bandwidth limit on client session 3000000 bytes per second (--max-bps).
# 2) use fingerprints (-f)
# 3) use 3 relay threads (-m 3)
# 4) use min UDP relay port 32355 and max UDP relay port 65535
# 5) "-r north.gov" means "use authentication realm north.gov"
# 6) "--user=ninefingers:0xbc807ee29df3c9ffa736523fb2c4e8ee" means
# "allow user 'ninefinger' with generated key '0xbc807ee29df3c9ffa736523fb2c4e8ee' ".
# 7) "--user=gorst:hero" means "allow user 'gorst' with password 'hero' ".
# 8) "--log-file=stdout" means that all log output will go to the stdout.
# 9) "-v" means normal verbose mode (with some moderate logging).
# 10) --no-dtls and --no-tls measn that we are not using DTLS & TLS protocols here
# (for the sake of simplicity).
# 11) --alternate-server options set the "slave" servers.
# Other parameters (config file name, etc) are default.
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
PATH="./bin/:../bin/:../../bin/:${PATH}" turnserver --syslog -a -L 127.0.0.1 -E 127.0.0.1 --max-bps=3000000 -f -m 3 --min-port=32355 --max-port=65535 --user=ninefingers:0xbc807ee29df3c9ffa736523fb2c4e8ee --user=gorst:hero -r north.gov --log-file=stdout -v --no-dtls --no-tls --alternate-server=127.0.0.1:3333 --alternate-server=127.0.0.1:4444 $@

View File

@ -0,0 +1,37 @@
#!/bin/sh
#
# This is an example of a SLAVE TURN server that accepts
# the redirected requests.
#
# The TURN Server is started in
# secure mode (when authentication is used) - see option -a
# that means "use long-term credential mechanism".
#
# We start here a TURN Server listening on IPv4 address
# 127.0.0.1. We use 127.0.0.1 as the relay address, too.
#
# Other options:
#
# 1) set bandwidth limit on client session 3000000 bytes per second (--max-bps).
# 2) use fingerprints (-f)
# 3) use 3 relay threads (-m 3)
# 4) use min UDP relay port 10000 and max UDP relay port 19999
# 5) "-r north.gov" means "use authentication realm north.gov"
# 6) "--user=ninefingers:0xbc807ee29df3c9ffa736523fb2c4e8ee" means
# "allow user 'ninefinger' with generated key '0xbc807ee29df3c9ffa736523fb2c4e8ee' ".
# 7) "--user=gorst:hero" means "allow user 'gorst' with password 'hero' ".
# 8) "--log-file=stdout" means that all log output will go to the stdout.
# 9) "-v" means normal verbose mode (with some moderate logging).
# 10) --no-dtls and --no-tls measn that we are not using DTLS & TLS protocols here
# (for the sake of simplicity).
# 11) -p 3333 means that we are using UDP & TCP listening port 3333.
# Other parameters (config file name, etc) are default.
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
PATH="./bin/:../bin/:../../bin/:${PATH}" turnserver --syslog -a -L 127.0.0.1 -E 127.0.0.1 --max-bps=3000000 -f -m 3 --min-port=10000 --max-port=19999 --user=ninefingers:0xbc807ee29df3c9ffa736523fb2c4e8ee --user=gorst:hero -r north.gov --log-file=stdout -v --no-dtls --no-tls -p 3333 --cli-port=5767 $@

View File

@ -0,0 +1,37 @@
#!/bin/sh
#
# This is an example of a SLAVE TURN server that accepts
# the redirected requests.
#
# The TURN Server is started in
# secure mode (when authentication is used) - see option -a
# that means "use long-term credential mechanism".
#
# We start here a TURN Server listening on IPv4 address
# 127.0.0.1. We use 127.0.0.1 as the relay address, too.
#
# Other options:
#
# 1) set bandwidth limit on client session 3000000 bytes per second (--max-bps).
# 2) use fingerprints (-f)
# 3) use 3 relay threads (-m 3)
# 4) use min UDP relay port 20000 and max UDP relay port 29999
# 5) "-r north.gov" means "use authentication realm north.gov"
# 6) "--user=ninefingers:0xbc807ee29df3c9ffa736523fb2c4e8ee" means
# "allow user 'ninefinger' with generated key '0xbc807ee29df3c9ffa736523fb2c4e8ee' ".
# 7) "--user=gorst:hero" means "allow user 'gorst' with password 'hero' ".
# 8) "--log-file=stdout" means that all log output will go to the stdout.
# 9) "-v" means normal verbose mode (with some moderate logging).
# 10) --no-dtls and --no-tls measn that we are not using DTLS & TLS protocols here
# (for the sake of simplicity).
# 11) -p 4444 means that we are using UDP & TCP listening port 4444.
# Other parameters (config file name, etc) are default.
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
PATH="./bin/:../bin/:../../bin/:${PATH}" turnserver --syslog -a -L 127.0.0.1 -E 127.0.0.1 --max-bps=3000000 -f -m 3 --min-port=20000 --max-port=29999 --user=ninefingers:0xbc807ee29df3c9ffa736523fb2c4e8ee --user=gorst:hero -r north.gov --log-file=stdout -v --no-dtls --no-tls -p 4444 --cli-port=5768 $@

View File

@ -0,0 +1,29 @@
#!/bin/sh
#
# This is an example of a script to run a "secure" TURN TCP client
# with the long-term credentials mechanism and with
# TCP relay endpoints (RFC 6062).
#
# Options:
#
# 1) -T is present, it means that TCP networking is used, with TCP relay endpoints (RFC 6062).
# 5) -n 1000 means 1000 messages per single emulated client. Messages
# are sent with interval of 20 milliseconds, to emulate an RTP stream.
# 6) -m 10 means that 10 clients are emulated.
# 7) -l 170 means that the payload size of the packets is 170 bytes
# (like average audio RTP packet).
# 8) -y means that the clients will connect to the 'neighbor' clients, no peer app will be used.
# 9) -g means "set DONT_FRAGMENT parameter in TURN requests".
# 10) -u gorst means that if the server challenges the client with
# authentication challenge, then we use account "gorst".
# 11) -w hero sets the password for the account as "hero".
# 12) 127.0.0.1 (the last parameter) is the TURN Server IP address.
#
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -T -n 1000 -m 10 -l 170 -y -g -u gorst -w hero $@ 127.0.0.1

View File

@ -0,0 +1,31 @@
#!/bin/sh
#
# This is an example of a script to run a "secure" TURN UDP client
# with the long-term credentials mechanism,
# in client-to-client communication patter.
#
# Options:
#
# 1) -t is absent, it means that UDP networking is used.
# 5) -n 1000 means 1000 messages per single emulated client. Messages
# are sent with interval of 20 milliseconds, to emulate an RTP stream.
# 6) -m 10 means that 10 clients are emulated.
# 7) -l 170 means that the payload size of the packets is 170 bytes
# (like average audio RTP packet).
# 8) -y means that the clients will be connecting to each other and the peer will not be used.
# 9) -g means "set DONT_FRAGMENT parameter in TURN requests".
# 10) -u ninefingers means that if the server challenges the client with
# authentication challenge, then we use account "ninefingers".
# 11) -w youhavetoberealistic sets the password for the account as "youhavetoberealistic".
# 12) -s option is absent - it means that the client will be using
# the "channel" mechanism for data.
# 13) 127.0.0.1 (the last parameter) is the TURN Server IP address.
#
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -n 1000 -m 10 -l 170 -g -u ninefingers -w youhavetoberealistic -y $@ 127.0.0.1

View File

@ -0,0 +1,49 @@
#!/bin/sh
#
# This is an example of a script to run a DOS attack in a
# "secure" environment
#
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/
while [ 0 ] ; do
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -G -O -n 10 -m 10 -l 170 -g -u ninefingers -w youhavetoberealistic -y $@ ::1 &
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -G -O -n 10 -m 10 -l 170 -e 127.0.0.1 -X -g -u ninefingers -w youhavetoberealistic $@ ::1 &
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -G -O -S -k turn_client_pkey.pem -n 10 -m 10 -l 170 -e ::1 -x -g -u ninefingers -w youhavetoberealistic -s $@ 127.0.0.1 &
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -G -O -t -n 30 -m 10 -l 170 -e 127.0.0.1 -X -g -u gorst -w hero $@ ::1 &
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -G -O -T -n 10 -m 10 -l 170 -y -g -u gorst -w hero $@ ::1 &
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -G -O -T -S -k turn_client_pkey.pem -n 10 -m 10 -l 170 -y -g -u gorst -w hero $@ ::1 &
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -G -O -t -S -k turn_client_pkey.pem -n 10 -m 10 -l 170 -e 127.0.0.1 -X -g -u gorst -w hero $@ ::1 &
sleep 2
type killall >>/dev/null 2>>/dev/null
ER=$?
if [ ${ER} -eq 0 ] ; then
killall turnutils_uclient >>/dev/null 2>>/dev/null
fi
type pkill >>/dev/null 2>>/dev/null
ER=$?
if [ ${ER} -eq 0 ] ; then
pkill turnutils_u >>/dev/null 2>>/dev/null
pkill turnutils_uclie >>/dev/null 2>>/dev/null
pkill turnutils_uclient >>/dev/null 2>>/dev/null
else
sleep 10
fi
done

View File

@ -0,0 +1,36 @@
#!/bin/sh
#
# This is an example of a script to run a "secure" TURN DTLS client
# with the long-term credentials mechanism.
#
# Options:
#
# 1) -t is absent, it means that UDP networking is used.
# 2) -S means "SSL protocol with default encryption"
# 3) -i absent.
# 4) -k sets private key file for TLS.
# 5) -n 1000 means 1000 messages per single emulated client. Messages
# are sent with interval of 20 milliseconds, to emulate an RTP stream.
# 6) -m 10 means that 10 clients are emulated.
# 7) -l 170 means that the payload size of the packets is 170 bytes
# (like average audio RTP packet).
# 8) -e 127.0.0.1 means that the clients will use peer IPv4 address 127.0.0.1.
# 9) -g means "set DONT_FRAGMENT parameter in TURN requests".
# 10) -u ninefingers means that if the server challenges the client with
# authentication challenge, then we use account "ninefingers".
# 11) -w youhavetoberealistic sets the password for the account.
# 12) -s option absent - that means that the client will be using
# the channel mechanism for data.
# 13) 127.0.0.1 (the last parameter) is the TURN Server IP address.
# We use IPv6 - to - IPv4 here to illustrate how the TURN Server
# converts the traffic from IPv6 to IPv4 and back.
#
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -S -k turn_client_pkey.pem -n 1000 -m 10 -l 170 -e 127.0.0.1 -X -g -u ninefingers -w youhavetoberealistic $@ 127.0.0.1

View File

@ -0,0 +1,36 @@
#!/bin/sh
#
# This is an example of a script to run a "secure" TURN DTLS client
# with the long-term credentials mechanism and with certificate check.
#
# Options:
#
# 1) -t is absent, it means that UDP networking is used.
# 2) -S means "SSL protocol with default encryption"
# 3) -i sets certificate file for TLS. -R sets certificate check mode.
# -E sets CA file for certificate check.
# 4) -k sets private key file for TLS.
# 5) -n 1000 means 1000 messages per single emulated client. Messages
# are sent with interval of 20 milliseconds, to emulate an RTP stream.
# 6) -m 10 means that 10 clients are emulated.
# 7) -l 170 means that the payload size of the packets is 170 bytes
# (like average audio RTP packet).
# 8) -e 127.0.0.1 means that the clients will use peer IPv4 address 127.0.0.1.
# 9) -g means "set DONT_FRAGMENT parameter in TURN requests".
# 10) -u bolt means that if the server challenges the client with
# authentication challenge, then we use account "bolt".
# 11) -w kwyjibo sets the password for the account.
# 12) -s option means that the client will be using "send" mechanism for data.
# 13) 127.0.0.1 (the last parameter) is the TURN Server IP address.
# We use IPv6 - to - IPv4 here to illustrate how the TURN Server
# converts the traffic from IPv6 to IPv4 and back.
#
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -S -i turn_server_cert.pem -k turn_server_pkey.pem -E turn_server_cert.pem -n 1000 -m 10 -l 170 -e 127.0.0.1 -g -u bolt -w kwyjibo -s -X $@ 127.0.0.1

View File

@ -0,0 +1,35 @@
#!/bin/sh
#
# This is an example how to start a TURN Server in
# secure mode (when authentication is used) - see option -a
# that means "use long-term credential mechanism".
#
# We start here a TURN Server listening on IPv4 address
# 127.0.0.1 and on IPv6 address ::1. We use 127.0.0.1 as
# IPv4 relay address, and we use ::1 as IPv6 relay address.
#
# Other options:
#
# 1) set bandwidth limit on client session 3000000 bytes per second (--max-bps).
# 2) use fingerprints (-f)
# 3) use 10 relay threads (-m 10)
# 4) use min UDP relay port 32355 and max UDP relay port 65535
# 5) "-r north.gov" means "use authentication realm north.gov"
# 6) "--user=ninefingers:youhavetoberealistic" means
# "allow user 'ninefinger' with password 'youhavetoberealistic' ".
# 7) "--user=gorst:hero" means "allow user 'gorst' with password 'hero' ".
# 8) "--cert=turn_server_cert.pem" sets the OpenSSL certificate file name.
# 9) "--pkey=turn_server_pkey.pem" sets the OpenSSL private key name.
# 10) "--log-file=stdout" means that all log output will go to the stdout.
# 11) "-v" means normal verbose mode (with some moderate logging).
# 12) --cipher-list=ALL:SSLv2 means that we support all OpenSSL ciphers, including SSLv2
# Other parameters (config file name, etc) are default.
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
PATH="./bin/:../bin/:../../bin/:${PATH}" turnserver --syslog -a -L 127.0.0.1 -L ::1 -E 127.0.0.1 -E ::1 --max-bps=3000000 -f -m 10 --min-port=32355 --max-port=65535 --user=ninefingers:youhavetoberealistic --user=gorst:hero -r north.gov --cert=turn_server_cert.pem --pkey=turn_server_pkey.pem --log-file=stdout -v --cipher-list=ALL:SSLv2 $@

View File

@ -0,0 +1,38 @@
#!/bin/sh
#
# This is an example how to start a TURN Server in
# secure mode (when authentication is used) - see option -a
# that means "use long-term credential mechanism".
#
# This script shows how to use certificate check option.
#
# We start here a TURN Server listening on IPv4 address
# 127.0.0.1 and on IPv6 address ::1. We use 127.0.0.1 as
# IPv4 relay address, and we use ::1 as IPv6 relay address.
#
# Other options:
#
# 1) set bandwidth limit on client session 3000000 bytes per second (--max-bps).
# 2) use fingerprints (-f)
# 3) use 10 relay threads (-m 10)
# 4) use min UDP relay port 32355 and max UDP relay port 65535
# 5) "-r bolt.co" means "use authentication realm 'bolt.co'"
# 6) "--user=ninefingers:youhavetoberealistic" means "allow user
# 'ninefinger' with password 'youhavetoberealistic'.".
# 7) "--user=bolt:kwyjibo" means "allow user 'bolt' with password 'kwyjibo' ".
# 8) "--cert=..." sets the OpenSSL certificate file name.
# 9) "--pkey=..." sets the OpenSSL private key name.
# 10) --CA-file sets the CA file for client certificate check.
# 11) "--log-file=stdout" means that all log output will go to the stdout.
# 12) "-v" means normal verbose mode (with some moderate logging).
# 13) --cipher-list="ALL:SSLv2:!eNULL:!aNULL:!NULL" measn "all ciphers, except anonymous".
# Other parameters (config file name, etc) are default.
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
PATH="./bin/:../bin/:../../bin/:${PATH}" turnserver --syslog -a -L 127.0.0.1 -L ::1 -E 127.0.0.1 -E ::1 --max-bps=3000000 -f -m 10 --min-port=32355 --max-port=65535 --user=ninefingers:youhavetoberealistic --user=bolt:kwyjibo -r bolt.co --cert=turn_server_cert.pem --pkey=turn_server_pkey.pem --CA-file=turn_server_cert.pem --log-file=stdout -v --cipher-list="ALL:SSLv2:!eNULL:!aNULL:!NULL" $@

View File

@ -0,0 +1,31 @@
#!/bin/sh
#
# This is an example of a script to run a "secure" TURN TCP client
# with the long-term credentials mechanism.
#
# Options:
#
# 1) -t is present, it means that TCP networking is used.
# 5) -n 1000 means 1000 messages per single emulated client. Messages
# are sent with interval of 20 milliseconds, to emulate an RTP stream.
# 6) -m 10 means that 10 clients are emulated.
# 7) -l 170 means that the payload size of the packets is 170 bytes
# (like average audio RTP packet).
# 8) -e 127.0.0.1 means that the clients will use peer address 127.0.0.1.
# 9) -g means "set DONT_FRAGMENT parameter in TURN requests".
# 10) -u gorst means that if the server challenges the client with
# authentication challenge, then we use account "gorst".
# 11) -w hero sets the password for the account as "hero".
# 12) -s option is absent - it means that the client will be using
# the "channel" mechanism for data.
# 13) ::1 (the last parameter) is the TURN Server IP address. We use IPv6 here
# to illustrate how the TURN Server convert the traffic from IPv6 to IPv4 and back.
#
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -t -n 3000 -m 10 -l 170 -e 127.0.0.1 -X -g -u gorst -w hero $@ ::1

View File

@ -0,0 +1,31 @@
#!/bin/sh
#
# This is an example of a script to run a "secure" TURN TCP client
# with the long-term credentials mechanism and with
# TCP relay endpoints (RFC 6062).
#
# Options:
#
# 1) -T is present, it means that TCP networking is used, with TCP relay endpoints (RFC 6062).
# 5) -n 1000 means 1000 messages per single emulated client. Messages
# are sent with interval of 20 milliseconds, to emulate an RTP stream.
# 6) -m 10 means that 10 clients are emulated.
# 7) -l 170 means that the payload size of the packets is 170 bytes
# (like average audio RTP packet).
# 8) -y means that the clients will connect to the 'neighbor' clients, no peer app will be used.
# 9) -g means "set DONT_FRAGMENT parameter in TURN requests".
# 10) -u gorst means that if the server challenges the client with
# authentication challenge, then we use account "gorst".
# 11) -w hero sets the password for the account as "hero".
# 12) 127.0.0.1 (the last parameter) is the TURN Server IP address. We use IPv4 here
# to illustrate how the TURN Server convert the traffic from IPv6 to IPv4 and back.
#
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -T -n 1000 -m 10 -l 170 -y -g -u gorst -w hero $@ 127.0.0.1

View File

@ -0,0 +1,34 @@
#!/bin/sh
#
# This is an example of a script to run a "secure" TURN TLS client
# with the long-term credentials mechanism.
#
# Options:
#
# 1) -t is present, it means that TCP networking is used.
# 2) -S means "SSL/TLS protocol with default cipher".
# 3) -i absent.
# 4) -k sets private key file for TLS.
# 5) -n 1000 means 1000 messages per single emulated client. Messages
# are sent with interval of 20 milliseconds, to emulate an RTP stream.
# 6) -m 10 means that 10 clients are emulated.
# 7) -l 170 means that the payload size of the packets is 170 bytes
# (like average audio RTP packet).
# 8) -e 127.0.0.1 means that the clients will use peer address 127.0.0.1.
# 9) -g means "set DONT_FRAGMENT parameter in TURN requests".
# 10) -u gorst means that if the server challenges the client with
# authentication challenge, then we use account "gorst".
# 11) -w hero sets the password for the account as "hero".
# 12) -s option means that the client will be using "send" mechanism for data.
# 13) ::1 (the last parameter) is the TURN Server IP address. We use IPv6 here
# to illustrate how the TURN Server convert the traffic from IPv6 to IPv4 and back.
#
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -t -S -k turn_client_pkey.pem -n 1000 -m 10 -l 170 -e 127.0.0.1 -X -g -u gorst -w hero $@ ::1

View File

@ -0,0 +1,35 @@
#!/bin/sh
#
# This is an example of a script to run a "secure" TURN TLS client
# with the long-term credentials mechanism and with
# TCP relay endpoints (RFC 6062).
#
# Options:
#
# 1) -T is present, it means that TCP networking is used, with TCP
# relay endpoints (RFC 6062.
# 2) -S means that "secure protocol", that is TLS in the case of TCP,
# will be used between the client and the TURN Server.
# 3) -i absent.
# 4) -k sets private key file for TLS.
# 5) -n 1000 means 1000 messages per single emulated client. Messages
# are sent with interval of 20 milliseconds, to emulate an RTP stream.
# 6) -m 10 means that 10 clients are emulated.
# 7) -l 170 means that the payload size of the packets is 170 bytes
# (like average audio RTP packet).
# 8) -y means that the clients will connect to the 'neighbor' clients, no peer app will be used.
# 9) -g means "set DONT_FRAGMENT parameter in TURN requests".
# 10) -u gorst means that if the server challenges the client with
# authentication challenge, then we use account "gorst".
# 11) -w hero sets the password for the account as "hero".
# 12) ::1 (the last parameter) is the TURN Server IP address. We use IPv6 here
# to illustrate how the TURN Server convert the traffic from IPv6 to IPv4 and back.
#
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/:/usr/postgres/9.2-pgdg/lib
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -T -S -k turn_client_pkey.pem -n 1000 -m 10 -l 170 -y -g -u gorst -w hero $@ ::1

View File

@ -0,0 +1,36 @@
#!/bin/sh
#
# This is an example of a script to run a "secure" TURN DTLS client
# with the long-term credentials mechanism and with certificate check.
#
# Options:
#
# 1) -t means that TCP networking is used.
# 2) -S means "SSL protocol with default encryption"
# 3) -i sets certificate file for TLS. -R sets certificate check mode.
# -E sets CA file for certificate check.
# 4) -k sets private key file for TLS.
# 5) -n 1000 means 1000 messages per single emulated client. Messages
# are sent with interval of 20 milliseconds, to emulate an RTP stream.
# 6) -m 10 means that 10 clients are emulated.
# 7) -l 170 means that the payload size of the packets is 170 bytes
# (like average audio RTP packet).
# 8) -e 127.0.0.1 means that the clients will use peer IPv4 address 127.0.0.1.
# 9) -g means "set DONT_FRAGMENT parameter in TURN requests".
# 10) -u bolt means that if the server challenges the client with
# authentication challenge, then we use account "bolt".
# 11) -w kwyjibo sets the password for the account.
# 12) -s option means that the client will be using "send" mechanism for data.
# 13) 127.0.0.1 (the last parameter) is the TURN Server IP address.
# We use IPv6 - to - IPv4 here to illustrate how the TURN Server
# converts the traffic from IPv6 to IPv4 and back.
#
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -t -S -i turn_server_cert.pem -k turn_server_pkey.pem -E turn_server_cert.pem -n 1000 -m 10 -l 170 -e 127.0.0.1 -X -g -u bolt -w kwyjibo -s $@ 127.0.0.1

View File

@ -0,0 +1,32 @@
#!/bin/sh
#
# This is an example of a script to run a "secure" TURN UDP client
# with the long-term credentials mechanism,
# in client-to-client communication patter.
#
# Options:
#
# 1) -t is absent, it means that UDP networking is used.
# 5) -n 1000 means 1000 messages per single emulated client. Messages
# are sent with interval of 20 milliseconds, to emulate an RTP stream.
# 6) -m 10 means that 10 clients are emulated.
# 7) -l 170 means that the payload size of the packets is 170 bytes
# (like average audio RTP packet).
# 8) -y means that the clients will be connecting to each other and the peer will not be used.
# 9) -g means "set DONT_FRAGMENT parameter in TURN requests".
# 10) -u ninefingers means that if the server challenges the client with
# authentication challenge, then we use account "ninefingers".
# 11) -w youhavetoberealistic sets the password for the account as "youhavetoberealistic".
# 12) -s option is present - it means that the client will be using
# the DATA mechanism for data.
# 13) ::1 (the last parameter) is the TURN Server IP address. We use IPv6 here
# to illustrate how the TURN Server convert the traffic from IPv6 to IPv4 and back.
#
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -s -n 1000 -m 10 -l 170 -g -u ninefingers -w youhavetoberealistic -y $@ ::1

View File

@ -0,0 +1,32 @@
#!/bin/sh
#
# This is an example of a script to run a "secure" TURN UDP client
# with the long-term credentials mechanism.
#
# Options:
#
# 1) -t is absent, it means that UDP networking is used.
# 5) -n 1000 means 1000 messages per single emulated client. Messages
# are sent with interval of 20 milliseconds, to emulate an RTP stream.
# 6) -m 10 means that 10 clients are emulated.
# 7) -l 170 means that the payload size of the packets is 170 bytes
# (like average audio RTP packet).
# 8) -e 127.0.0.1 means that the clients will use peer address 127.0.0.1.
# 9) -g means "set DONT_FRAGMENT parameter in TURN requests".
# 10) -u ninefingers means that if the server challenges the client with
# authentication challenge, then we use account "ninefingers".
# 11) -w youhavetoberealistic sets the password for the account as "youhavetoberealistic".
# 12) -s option is absent - it means that the client will be using
# the "channel" mechanism for data.
# 13) ::1 (the last parameter) is the TURN Server IP address. We use IPv6 here
# to illustrate how the TURN Server convert the traffic from IPv6 to IPv4 and back.
#
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -n 1000 -m 10 -l 170 -e 127.0.0.1 -X -g -u ninefingers -w youhavetoberealistic $@ ::1

View File

@ -0,0 +1,34 @@
#!/bin/sh
#
# This is an example how to start a TURN Server in
# secure mode with MySQL database for users
# with the long-term credentials mechanism.
#
# We start here a TURN Server listening on IPv4 address
# 127.0.0.1 and on IPv6 address ::1. We use 127.0.0.1 as
# IPv4 relay address, and we use ::1 as IPv6 relay address.
#
# Other options:
#
# 1) set bandwidth limit on client session 3000000 bytes per second (--max-bps).
# 2) use fingerprints (-f)
# 3) use 3 relay threads (-m 3)
# 4) use min UDP relay port 32355 and max UDP relay port 65535
# 5) "-r north.gov" means "use authentication realm north.gov"
# 6) --mysql-userdb="host=localhost dbname=coturn user=turn password=turn connect_timeout=30"
# means that local MySQL database "coturn" will be used, with database user "turn" and
# database user password "turn", and connection timeout 30 seconds.
# 7) "--cert=example_turn_server_cert.pem" sets the OpenSSL certificate file name.
# 8) "--pkey=example_turn_server_pkey.pem" sets the OpenSSL private key name.
# 9) "--log-file=stdout" means that all log output will go to the stdout.
# 10) --cipher-list=ALL:SSLv2 means that we support all OpenSSL ciphers, including SSLv2
# Other parameters (config file name, etc) are default.
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
PATH="./bin/:../bin/:../../bin/:${PATH}" turnserver -v --syslog -a -L 127.0.0.1 -L ::1 -E 127.0.0.1 -E ::1 --max-bps=3000000 -f -m 3 --min-port=32355 --max-port=65535 -r north.gov --mysql-userdb="host=localhost dbname=coturn user=turn password=turn connect_timeout=30" --cert=turn_server_cert.pem --pkey=turn_server_pkey.pem --log-file=stdout --cipher-list=ALL:SSLv2 $@

View File

@ -0,0 +1,37 @@
#!/bin/sh
#
# This is an example how to start a TURN Server in
# secure mode with Postgres database for users
# with the long-term credentials mechanism.
#
# We start here a TURN Server listening on IPv4 address
# 127.0.0.1 and on IPv6 address ::1. We use 127.0.0.1 as
# IPv4 relay address, and we use ::1 as IPv6 relay address.
#
# Other options:
#
# 1) set bandwidth limit on client session 3000000 bytes per second (--max-bps).
# 2) use fingerprints (-f)
# 3) use 3 relay threads (-m 3)
# 4) use min UDP relay port 32355 and max UDP relay port 65535
# 5) "-r north.gov" means "use authentication realm north.gov"
# 6) --psql-userdb="host=localhost dbname=coturn user=turn password=turn connect_timeout=30"
# means that local database "coturn" will be used, with database user "turn" and database user
# password "turn".
# 7) "--cert=example_turn_server_cert.pem" sets the OpenSSL certificate file name.
# 8) "--pkey=example_turn_server_pkey.pem" sets the OpenSSL private key name.
# 9) "--log-file=stdout" means that all log output will go to the stdout.
# 10) --cipher-list=ALL:SSLv2 means that we support all OpenSSL ciphers, including SSLv2
# Other parameters (config file name, etc) are default.
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
PATH="./bin/:../bin/:../../bin/:${PATH}" turnserver -v --syslog -a -L 127.0.0.1 -L ::1 -E 127.0.0.1 -E ::1 --max-bps=3000000 -f -m 3 --min-port=32355 --max-port=65535 -r north.gov --psql-userdb="host=localhost dbname=coturn user=turn password=turn connect_timeout=30" --cert=turn_server_cert.pem --pkey=turn_server_pkey.pem --log-file=stdout --cipher-list=ALL:SSLv2 $@
# Newer PostgreSQL style connection string example:
# PATH="./bin/:../bin/:../../bin/:${PATH}" turnserver -v --syslog -a -L 127.0.0.1 -L ::1 -E 127.0.0.1 -E ::1 --max-bps=3000000 -f -m 3 --min-port=32355 --max-port=65535 -r north.gov --psql-userdb=postgresql://turn:turn@/turn --cert=turn_server_cert.pem --pkey=turn_server_pkey.pem --log-file=stdout --cipher-list=ALL:SSLv2 $@

View File

@ -0,0 +1,37 @@
#!/bin/sh
#
# This is an example how to start a TURN Server in
# secure mode with Redis database for users
# with the long-term credentials mechanism.
#
# We start here a TURN Server listening on IPv4 address
# 127.0.0.1 and on IPv6 address ::1. We use 127.0.0.1 as
# IPv4 relay address, and we use ::1 as IPv6 relay address.
#
# Other options:
#
# 1) set bandwidth limit on client session 3000000 bytes per second (--max-bps).
# 2) use fingerprints (-f)
# 3) use 3 relay threads (-m 3)
# 4) use min UDP relay port 32355 and max UDP relay port 65535
# 5) "-r north.gov" means "use authentication realm north.gov"
# 6) --redis-userdb="ip=127.0.0.1 dbname=2 password=turn connect_timeout=30"
# means that local Redis database 0 will be used,
# database password is "turn", and connection timeout 30 seconds.
# 7) --redis-statsdb="ip=127.0.0.1 dbname=3 password=turn connect_timeout=30"
# means that we want to use Redis for status and statistics information,
# and this will be the database number 3.
# 8) "--cert=example_turn_server_cert.pem" sets the OpenSSL certificate file name.
# 9) "--pkey=example_turn_server_pkey.pem" sets the OpenSSL private key name.
# 10) "--log-file=stdout" means that all log output will go to the stdout.
# 11) --cipher-list=ALL:SSLv2 means that we support all OpenSSL ciphers, including SSLv2
# Other parameters (config file name, etc) are default.
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
PATH="./bin/:../bin/:../../bin/:${PATH}" turnserver -v --syslog -a -L 127.0.0.1 -L ::1 -E 127.0.0.1 -E ::1 --max-bps=3000000 -f -m 3 --min-port=32355 --max-port=65535 -r north.gov --redis-userdb="ip=127.0.0.1 dbname=2 password=turn connect_timeout=30" --redis-statsdb="ip=127.0.0.1 dbname=3 password=turn connect_timeout=30" --cert=turn_server_cert.pem --pkey=turn_server_pkey.pem --log-file=stdout --cipher-list=ALL:SSLv2 $@

View File

@ -0,0 +1,36 @@
#!/bin/sh
#
# This is an example of a script to run a "secure" TURN DTLS client
# with "mobile" option and the long-term credentials mechanism.
#
# Options:
#
# 1) -t is absent, it means that UDP networking is used.
# 2) -S means "SSL protocol with default encryption"
# 3) -i absent.
# 4) -k sets private key file for TLS.
# 5) -n 1000 means 1000 messages per single emulated client. Messages
# are sent with interval of 20 milliseconds, to emulate an RTP stream.
# 6) -m 10 means that 10 clients are emulated.
# 7) -l 170 means that the payload size of the packets is 170 bytes
# (like average audio RTP packet).
# 8) -e 127.0.0.1 means that the clients will use peer IPv4 address 127.0.0.1.
# 9) -g means "set DONT_FRAGMENT parameter in TURN requests".
# 10) -u ninefingers means that if the server challenges the client with
# authentication challenge, then we use account "ninefingers".
# 11) -w youhavetoberealistic sets the password for the account.
# 12) -s option means that the client will be using "send" mechanism for data.
# 13) -M turns on the Mobile ICE TURN functionality.
# 14) 127.0.0.1 (the last parameter) is the TURN Server IP address.
# We use IPv6 - to - IPv4 here to illustrate how the TURN Server
# converts the traffic from IPv6 to IPv4 and back.
#
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -S -k turn_client_pkey.pem -n 1000 -m 10 -l 170 -e 127.0.0.1 -X -g -u ninefingers -w youhavetoberealistic -s -M $@ 127.0.0.1

View File

@ -0,0 +1,36 @@
#!/bin/sh
#
# This is an example how to start a "mobile" TURN Server in
# secure mode (when authentication is used) - see option -a
# that means "use long-term credential mechanism".
#
# We start here a TURN Server listening on IPv4 address
# 127.0.0.1 and on IPv6 address ::1. We use 127.0.0.1 as
# IPv4 relay address, and we use ::1 as IPv6 relay address.
#
# Other options:
#
# 1) set bandwidth limit on client session 3000000 bytes per second (--max-bps).
# 2) use fingerprints (-f)
# 3) use 10 relay threads (-m 10)
# 4) use min UDP relay port 32355 and max UDP relay port 65535
# 5) "-r north.gov" means "use authentication realm north.gov"
# 6) "--user=ninefingers:0xbc807ee29df3c9ffa736523fb2c4e8ee" means
# "allow user 'ninefinger' with generated key '0xbc807ee29df3c9ffa736523fb2c4e8ee' ".
# 7) "--user=gorst:hero" means "allow user 'gorst' with password 'hero' ".
# 8) "--cert=turn_server_cert.pem" sets the OpenSSL certificate file name.
# 9) "--pkey=turn_server_pkey.pem" sets the OpenSSL private key name.
# 10) "--log-file=stdout" means that all log output will go to the stdout.
# 11) "-v" means normal verbose mode (with some moderate logging).
# 12) "--mobility" turns on the Mobile ICE TURN functionality.
# 13) --cipher-list=ALL:SSLv2 means that we support all OpenSSL ciphers, including SSLv2
# Other parameters (config file name, etc) are default.
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
PATH="./bin/:../bin/:../../bin/:${PATH}" turnserver --syslog -a -L 127.0.0.1 -L ::1 -E 127.0.0.1 -E ::1 --max-bps=3000000 -f -m 10 --min-port=32355 --max-port=65535 --user=ninefingers:0xbc807ee29df3c9ffa736523fb2c4e8ee --user=gorst:hero -r north.gov --cert=turn_server_cert.pem --pkey=turn_server_pkey.pem --log-file=stdout -v --mobility --cipher-list=ALL:SSLv2 $@

View File

@ -0,0 +1,32 @@
#!/bin/sh
#
# This is an example of a script to run a "secure" "mobile"
# TURN TCP client with the long-term credentials mechanism.
#
# Options:
#
# 1) -t is present, it means that TCP networking is used.
# 5) -n 1000 means 1000 messages per single emulated client. Messages
# are sent with interval of 20 milliseconds, to emulate an RTP stream.
# 6) -m 10 means that 10 clients are emulated.
# 7) -l 170 means that the payload size of the packets is 170 bytes
# (like average audio RTP packet).
# 8) -e 127.0.0.1 means that the clients will use peer address 127.0.0.1.
# 9) -g means "set DONT_FRAGMENT parameter in TURN requests".
# 10) -u gorst means that if the server challenges the client with
# authentication challenge, then we use account "gorst".
# 11) -w hero sets the password for the account as "hero".
# 12) -s option is absent - it means that the client will be using
# the "channel" mechanism for data.
# 13) -M turns on the Mobile ICE TURN functionality.
# 14) ::1 (the last parameter) is the TURN Server IP address. We use IPv6 here
# to illustrate how the TURN Server convert the traffic from IPv6 to IPv4 and back.
#
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -t -n 3000 -m 10 -l 170 -e 127.0.0.1 -X -g -u gorst -w hero -M $@ ::1

View File

@ -0,0 +1,36 @@
#!/bin/sh
#
# This is an example of a script to run a "secure" TURN TLS client
# with "mobile" option and with the long-term credentials mechanism and with
# TCP relay endpoints (RFC 6062).
#
# Options:
#
# 1) -T is present, it means that TCP networking is used, with TCP
# relay endpoints (RFC 6062.
# 2) -S means that "secure protocol", that is TLS in the case of TCP,
# will be used between the client and the TURN Server.
# 3) -i absent.
# 4) -k sets private key file for TLS.
# 5) -n 1000 means 1000 messages per single emulated client. Messages
# are sent with interval of 20 milliseconds, to emulate an RTP stream.
# 6) -m 10 means that 10 clients are emulated.
# 7) -l 170 means that the payload size of the packets is 170 bytes
# (like average audio RTP packet).
# 8) -y means that the clients will connect to the 'neighbor' clients, no peer app will be used.
# 9) -g means "set DONT_FRAGMENT parameter in TURN requests".
# 10) -u gorst means that if the server challenges the client with
# authentication challenge, then we use account "gorst".
# 11) -w hero sets the password for the account as "hero".
# 12) -M turns on the Mobile ICE TURN functionality.
# 13) ::1 (the last parameter) is the TURN Server IP address. We use IPv6 here
# to illustrate how the TURN Server convert the traffic from IPv6 to IPv4 and back.
#
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/:/usr/postgres/9.2-pgdg/lib
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -T -S -k turn_client_pkey.pem -n 1000 -m 10 -l 170 -y -g -u gorst -w hero -M $@ ::1

View File

@ -0,0 +1,33 @@
#!/bin/sh
#
# This is an example of a script to run a "secure" TURN UDP client
# with "mobile" option and with the long-term credentials mechanism.
#
# Options:
#
# 1) -t is absent, it means that UDP networking is used.
# 5) -n 1000 means 1000 messages per single emulated client. Messages
# are sent with interval of 20 milliseconds, to emulate an RTP stream.
# 6) -m 10 means that 10 clients are emulated.
# 7) -l 170 means that the payload size of the packets is 170 bytes
# (like average audio RTP packet).
# 8) -e 127.0.0.1 means that the clients will use peer address 127.0.0.1.
# 9) -g means "set DONT_FRAGMENT parameter in TURN requests".
# 10) -u ninefingers means that if the server challenges the client with
# authentication challenge, then we use account "ninefingers".
# 11) -w youhavetoberealistic sets the password for the account as "youhavetoberealistic".
# 12) -s option is absent - it means that the client will be using
# the "channel" mechanism for data.
# 13) -M turns on the Mobile ICE TURN functionality.
# 14) ::1 (the last parameter) is the TURN Server IP address. We use IPv6 here
# to illustrate how the TURN Server convert the traffic from IPv6 to IPv4 and back.
#
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -n 1000 -m 10 -l 170 -e 127.0.0.1 -X -g -u ninefingers -w youhavetoberealistic -M $@ ::1

16
examples/scripts/peer.sh Executable file
View File

@ -0,0 +1,16 @@
#!/bin/sh
#
# This is a script for the peer application,
# for testing only purposes. It opens UDP echo-like sockets
# on IPv4 address 127.0.0.1 and IPv6 address ::1.
# The default port 3480 is used.
#
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/
export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:/usr/local/lib/
PATH=examples/bin/:bin/:../bin:${PATH} turnutils_peer -L 127.0.0.1 -L ::1 -L 0.0.0.0 $@

View File

@ -0,0 +1,26 @@
This directory contains various example scripts for the TURN server
functionality illustration.
1) peer.sh starts the "peer" application that serves as a peer for all examples.
2) "basic" directory contains set of scripts which works together to demonstrate
very basic anynymous functionality of the TURN server. The "peer.sh" must be used, too.
3) "longtermsecure" directory contains set of scripts demonstrating the long-term authentication
mechanism (peer.sh to be used, too).
4) "longtermsecuredb" shows how to start TURN server with database. The clients from the
directory "longtermsecure" can be used with the relay scripts in the "longtermsecuredb"
directory. Of course, the database (PostgreSQL or MySQL) must be set for these scripts
to work correctly.
5) "restapi" shows how to use TURN REST API.
6) "shorttermsecure" shows how to use the short-term authentication mechanism. The short term
mechanism is always used with the database.
7) "loadbalance" shows how to use the simple load-balancing mechanism based upon the
ALTERNATE-SERVER functionality.

View File

@ -0,0 +1,36 @@
#!/bin/sh
#
# This is an example how to start a TURN Server in
# secure 'static' 'secret' mode (see TURNServerRESTAPI.pdf)
# with the long-term credentials mechanism.
#
# We start here a TURN Server listening on IPv4 address
# 127.0.0.1 and on IPv6 address ::1. We use 127.0.0.1 as
# IPv4 relay address, and we use ::1 as IPv6 relay address.
#
# Other options:
#
# 1) set bandwidth limit on client session 3000000 bytes per second (--max-bps).
# 2) use fingerprints (-f)
# 3) use 3 relay threads (-m 3)
# 4) use min UDP relay port 32355 and max UDP relay port 65535
# 5) --use-auth-secret means that we are using 'secret' authentication mode.
# 6) --static-auth-secret=logen means that we will be using 'static' secret value.
# 7) --realm=north.gov sets realm value as "north.gov".
# 8) "--cert=example_turn_server_cert.pem" sets the OpenSSL certificate file name.
# 9) "--pkey=example_turn_server_pkey.pem" sets the OpenSSL private key name.
# 10) "--log-file=stdout" means that all log output will go to the stdout.
# 11) "-q 100" means that single user can create no more than 100 sessions
# 12) "-Q 300" means that there may be no more than 300 sessions totally
# 13) --cipher-list=ALL:SSLv2 means that we support all OpenSSL ciphers, including SSLv2.
# Other parameters (config file name, etc) are default.
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
PATH="./bin/:../bin/:../../bin/:${PATH}" turnserver -v --syslog -a -L 127.0.0.1 -L ::1 -E 127.0.0.1 -E ::1 --max-bps=3000000 -f -m 3 --min-port=32355 --max-port=65535 --use-auth-secret --static-auth-secret=logen --realm=north.gov --cert=turn_server_cert.pem --pkey=turn_server_pkey.pem --log-file=stdout -q 100 -Q 300 --cipher-list=ALL:SSLv2 $@

View File

@ -0,0 +1,38 @@
#!/bin/sh
#
# This is an example how to start a TURN Server in
# secure 'dynamic' 'secret' mode (see TURNServerRESTAPI.pdf)
# with MySQL database for users information
# with the long-term credentials mechanism.
#
# We start here a TURN Server listening on IPv4 address
# 127.0.0.1 and on IPv6 address ::1. We use 127.0.0.1 as
# IPv4 relay address, and we use ::1 as IPv6 relay address.
#
# Other options:
#
# 1) set bandwidth limit on client session 3000000 bytes per second (--max-bps).
# 2) use fingerprints (-f)
# 3) use 3 relay threads (-m 3)
# 4) use min UDP relay port 32355 and max UDP relay port 65535
# 5) --use-auth-secret means that we are using 'secret' authentication mode.
# Absense of --static-auth-secret value means that we will be taking the secret value
# from the database ('dynamic' mode).
# 6) --realm=north.gov sets realm value as "north.gov".
# 7) --mysql-userdb="host=localhost dbname=coturn user=turn password=turn connect_timeout=30"
# means that local MySQL database "coturn" will be used, with database user "turn" and
# with database user password "turn", and connection timeout 30 seconds.
# 8) "--cert=example_turn_server_cert.pem" sets the OpenSSL certificate file name.
# 9) "--pkey=example_turn_server_pkey.pem" sets the OpenSSL private key name.
# 10) "--log-file=stdout" means that all log output will go to the stdout.
# 11) --cipher-list=ALL:SSLv2 means that we support all OpenSSL ciphers, including SSLv2
# Other parameters (config file name, etc) are default.
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
PATH="./bin/:../bin/:../../bin/:${PATH}" turnserver -v --syslog -a -L 127.0.0.1 -L ::1 -E 127.0.0.1 -E ::1 --max-bps=3000000 -f -m 3 --min-port=32355 --max-port=65535 --use-auth-secret --realm=north.gov --mysql-userdb="host=localhost dbname=coturn user=turn password=turn connect_timeout=30" --cert=turn_server_cert.pem --pkey=turn_server_pkey.pem --log-file=stdout --cipher-list=ALL:SSLv2 $@

View File

@ -0,0 +1,38 @@
#!/bin/sh
#
# This is an example how to start a TURN Server in
# secure 'dynamic' 'secret' mode (see TURNServerRESTAPI.pdf)
# with PostgreSQL database for users information
# with the long-term credentials mechanism.
#
# We start here a TURN Server listening on IPv4 address
# 127.0.0.1 and on IPv6 address ::1. We use 127.0.0.1 as
# IPv4 relay address, and we use ::1 as IPv6 relay address.
#
# Other options:
#
# 1) set bandwidth limit on client session 3000000 bytes per second (--max-bps).
# 2) use fingerprints (-f)
# 3) use 3 relay threads (-m 3)
# 4) use min UDP relay port 32355 and max UDP relay port 65535
# 5) --use-auth-secret means that we are using 'secret' authentication mode.
# Absense of --static-auth-secret value means that we will be taking the secret value
# from the database ('dynamic' mode).
# 6)--realm=north.gov sets realm value as "north.gov".
# 7) --psql-userdb="host=localhost dbname=coturn user=turn password=turn connect_timeout=30"
# means that local PostgreSQL database "coturn" will be used, with database user "turn" and
# with database user password "turn", and connection timeout 30 seconds.
# 8) "--cert=example_turn_server_cert.pem" sets the OpenSSL certificate file name.
# 9) "--pkey=example_turn_server_pkey.pem" sets the OpenSSL private key name.
# 10) "--log-file=stdout" means that all log output will go to the stdout.
# 11) --cipher-list=ALL:SSLv2 means that we support all OpenSSL ciphers, including SSLv2.
# Other parameters (config file name, etc) are default.
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
PATH="./bin/:../bin/:../../bin/:${PATH}" turnserver -v --syslog -a -L 127.0.0.1 -L ::1 -E 127.0.0.1 -E ::1 --max-bps=3000000 -f -m 3 --min-port=32355 --max-port=65535 --use-auth-secret --realm=north.gov --psql-userdb="host=localhost dbname=coturn user=turn password=turn connect_timeout=30" --cert=turn_server_cert.pem --pkey=turn_server_pkey.pem --log-file=stdout --cipher-list=ALL:SSLv2 $@

View File

@ -0,0 +1,38 @@
#!/bin/sh
#
# This is an example how to start a TURN Server in
# secure 'dynamic' 'secret' mode (see TURNServerRESTAPI.pdf)
# with Redis database for users information
# with the long-term credentials mechanism.
#
# We start here a TURN Server listening on IPv4 address
# 127.0.0.1 and on IPv6 address ::1. We use 127.0.0.1 as
# IPv4 relay address, and we use ::1 as IPv6 relay address.
#
# Other options:
#
# 1) set bandwidth limit on client session 3000000 bytes per second (--max-bps).
# 2) use fingerprints (-f)
# 3) use 3 relay threads (-m 3)
# 4) use min UDP relay port 32355 and max UDP relay port 65535
# 5) --use-auth-secret means that we are using 'secret' authentication mode.
# Absense of --static-auth-secret value means that we will be taking the secret value
# from the database ('dynamic' mode).
# 6) --realm=north.gov sets realm value as "north.gov".
# 7) --redis-userdb="ip=127.0.0.1 dbname=2 password=turn connect_timeout=30"
# means that local Redis database 0 will be used, with database
# password "turn", and connection timeout 30 seconds.
# 8) "--cert=example_turn_server_cert.pem" sets the OpenSSL certificate file name.
# 9) "--pkey=example_turn_server_pkey.pem" sets the OpenSSL private key name.
# 10) "--log-file=stdout" means that all log output will go to the stdout.
# 11) --cipher-list=ALL:SSLv2 means that we support all OpenSSL ciphers, including SSLv2.
# Other parameters (config file name, etc) are default.
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
PATH="./bin/:../bin/:../../bin/:${PATH}" turnserver -v --syslog -a -L 127.0.0.1 -L ::1 -E 127.0.0.1 -E ::1 --max-bps=3000000 -f -m 3 --min-port=32355 --max-port=65535 --use-auth-secret --realm=north.gov --redis-userdb="ip=127.0.0.1 dbname=2 password=turn connect_timeout=30" --cert=turn_server_cert.pem --pkey=turn_server_pkey.pem --log-file=stdout --redis-statsdb="ip=127.0.0.1 dbname=3 password=turn connect_timeout=30" --cipher-list=ALL:SSLv2 $@

View File

@ -0,0 +1,31 @@
#!/bin/sh
#
# This is an example of a script to run a "secure" TURN UDP client
# with the long-term credentials mechanism and with
# secret-based authorization (see TURNServerRESTAPI.pdf document).
#
# Options:
#
# 1) -t is absent, it means that UDP networking is used.
# 5) -n 1000 means 1000 messages per single emulated client. Messages
# are sent with interval of 20 milliseconds, to emulate an RTP stream.
# 6) -m 10 means that 10 clients are emulated.
# 7) -l 170 means that the payload size of the packets is 170 bytes
# (like average audio RTP packet).
# 8) -e 127.0.0.1 means that the clients will use peer address 127.0.0.1.
# 9) -g means "set DONT_FRAGMENT parameter in TURN requests".
# 10) -u ninefingers means that if the server challenges the client with
# authentication challenge, then we use account "ninefingers".
# 11) -W logen sets the secret for the secret-based authentication as "logen".
# 12) -s option is absent - it means that the client will be using
# the "channel" mechanism for data.
# 13) ::1 (the last parameter) is the TURN Server IPv6 address.
#
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -z 5 -n 10000 -s -m 10 -l 170 -e 127.0.0.1 -X -g -u ninefingers -W logen $@ ::1

View File

@ -0,0 +1,105 @@
#!/usr/bin/perl
#
# This is an example of Perl script maintaining dynamic shared secret
# database for the REST API
#
use strict;
use warnings;
use DBI;
use HTTP::Request::Common;
my $DBNAME="turn";
my $DBUSERNAME="turn";
my $DBPWD="turn";
my $DBHOST="localhost";
my $webserver = 'http://example.com/';
my $old_secret = "";
my $current_secret="";
my $INTERVAL=3600;
my $dbh;
$dbh = DBI->connect("DBI:mysql:$DBNAME;host=$DBHOST", $DBUSERNAME, $DBPWD)
|| die "Could not connect to database: $DBI::errstr";
$dbh->do('CREATE TABLE IF NOT EXISTS turn_secret (value varchar(512))');
my $c = $dbh->do("delete from turn_secret");
print "Deleted $c rows\n";
$dbh->disconnect();
do {
$dbh = DBI->connect("DBI:mysql:$DBNAME;host=$DBHOST", $DBUSERNAME, $DBPWD)
|| die "Could not connect to database: $DBI::errstr";
$dbh->do('CREATE TABLE IF NOT EXISTS turn_secret (value varchar(512))');
if(length($current_secret)) {
if(length($old_secret)) {
remove_secret($dbh, $old_secret);
}
$old_secret=$current_secret;
}
print "CURRENT SECRET TO BE (RE)GENERATED\n";
$current_secret = generate_secret();
insert_secret($dbh, $current_secret);
$dbh->disconnect();
#
# Web server interaction example:
# Here we can put code to submit this secret to the web server:
#
my $req = POST($webserver, Content => [param => $current_secret]);
$req->method('PUT');
print $req->as_string,"\n";
#
# Alternatively, you can use this link for compute-on-demand:
# https://github.com/alfreddatakillen/computeengineondemand
#
# write your code here.
#
sleep($INTERVAL);
} while(1);
sub remove_secret {
my $dbh = shift;
my $secret=shift;
my $c = $dbh->do("delete from turn_secret where value = '$secret'");
print "Deleted $c rows\n";
}
sub insert_secret {
my $dbh = shift;
my $secret=shift;
my $c = $dbh->do("insert into turn_secret values('$secret')");
print "Inserted $c rows\n";
}
sub generate_secret {
my @chars = ('0'..'9', 'A'..'F');
my $len = 8;
my $string;
while($len--){ $string .= $chars[rand @chars] };
return $string;
}

14
examples/scripts/rfc5769.sh Executable file
View File

@ -0,0 +1,14 @@
#!/bin/sh
#
# This is a script for RFC 5769 STUN protocol check.
# It checks whether the main code was compiled correctly.
#
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/
export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:/usr/local/lib/
PATH=examples/bin/:bin/:../bin:${PATH} turnutils_rfc5769check $@

View File

@ -0,0 +1,130 @@
#!/bin/sh
#
# This is an example of a script to run a DOS attack
# in a "secure" environment on a server with
# self-load-balancing option
#
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/
export SLEEP_TIME=9
while [ 0 ] ; do
rm -rf /var/log/turnserver/*
##########################
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -G -n 30 -m 10 -l 170 -g -u ninefingers -w youhavetoberealistic -y $@ ::1 &
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -G -n 30 -m 10 -l 170 -e 127.0.0.1 -X -g -u ninefingers -w youhavetoberealistic $@ ::1 &
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -G -S -k turn_client_pkey.pem -n 10 -m 10 -l 170 -e ::1 -x -g -u ninefingers -w youhavetoberealistic -s $@ 127.0.0.1 &
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -G -t -n 50 -m 10 -l 170 -e 127.0.0.1 -X -g -u gorst -w hero $@ ::1 &
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -G -T -n 30 -m 10 -l 170 -y -g -u gorst -w hero $@ ::1 &
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -G -T -S -k turn_client_pkey.pem -n 30 -m 10 -l 170 -y -g -u gorst -w hero $@ ::1 &
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -G -t -S -k turn_client_pkey.pem -n 30 -m 10 -l 170 -e 127.0.0.1 -X -g -u gorst -w hero $@ ::1 &
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -G -n 30 -m 10 -l 170 -g -u ninefingers -w youhavetoberealistic -y -p 12345 $@ ::1 &
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -G -n 30 -m 10 -l 170 -e 127.0.0.1 -X -g -u ninefingers -w youhavetoberealistic -p 12345 $@ ::1 &
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -G -S -k turn_client_pkey.pem -n 30 -m 10 -l 170 -e ::1 -x -g -u ninefingers -w youhavetoberealistic -s -p 12345 $@ 127.0.0.1 &
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -G -t -n 50 -m 10 -l 170 -e 127.0.0.1 -X -g -u gorst -w hero -p 12345 $@ ::1 &
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -G -T -n 30 -m 10 -l 170 -y -g -u gorst -w hero -p 12345 $@ ::1 &
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -G -T -S -k turn_client_pkey.pem -n 30 -m 10 -l 170 -y -g -u gorst -w hero -p 12345 $@ ::1 &
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -G -t -S -k turn_client_pkey.pem -n 30 -m 10 -l 170 -e 127.0.0.1 -X -g -u gorst -w hero -p 12345 $@ ::1 &
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -G -n 30 -m 10 -l 170 -g -u ninefingers -w youhavetoberealistic -y -p 12346 $@ ::1 &
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -G -n 30 -m 10 -l 170 -e 127.0.0.1 -X -g -u ninefingers -w youhavetoberealistic -p 12346 $@ ::1 &
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -G -S -k turn_client_pkey.pem -n 30 -m 10 -l 170 -e ::1 -x -g -u ninefingers -w youhavetoberealistic -s -p 12346 $@ 127.0.0.1 &
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -G -t -n 50 -m 10 -l 170 -e 127.0.0.1 -X -g -u gorst -w hero -p 12346 $@ ::1 &
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -G -T -n 30 -m 10 -l 170 -y -g -u gorst -w hero -p 12346 $@ ::1 &
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -G -T -S -k turn_client_pkey.pem -n 30 -m 10 -l 170 -y -g -u gorst -w hero -p 12346 $@ ::1 &
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -G -t -S -k turn_client_pkey.pem -n 30 -m 10 -l 170 -e 127.0.0.1 -X -g -u gorst -w hero -p 12346 $@ ::1 &
###########################
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -O -N -R -G -n 30 -m 10 -l 170 -g -u ninefingers -w youhavetoberealistic -y $@ ::1 &
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -O -N -R -G -n 30 -m 10 -l 170 -e 127.0.0.1 -X -g -u ninefingers -w youhavetoberealistic $@ ::1 &
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -O -N -R -G -S -k turn_client_pkey.pem -n 10 -m 10 -l 170 -e ::1 -x -g -u ninefingers -w youhavetoberealistic -s $@ 127.0.0.1 &
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -O -N -R -G -t -n 50 -m 10 -l 170 -e 127.0.0.1 -X -g -u gorst -w hero $@ ::1 &
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -O -N -R -G -T -n 30 -m 10 -l 170 -y -g -u gorst -w hero $@ ::1 &
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -O -N -R -G -T -S -k turn_client_pkey.pem -n 30 -m 10 -l 170 -y -g -u gorst -w hero $@ ::1 &
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -O -N -R -G -t -S -k turn_client_pkey.pem -n 30 -m 10 -l 170 -e 127.0.0.1 -X -g -u gorst -w hero $@ ::1 &
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -O -N -R -G -n 30 -m 10 -l 170 -g -u ninefingers -w youhavetoberealistic -y -p 12345 $@ ::1 &
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -O -N -R -G -n 30 -m 10 -l 170 -e 127.0.0.1 -X -g -u ninefingers -w youhavetoberealistic -p 12345 $@ ::1 &
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -O -N -R -G -S -k turn_client_pkey.pem -n 30 -m 10 -l 170 -e ::1 -x -g -u ninefingers -w youhavetoberealistic -s -p 12345 $@ 127.0.0.1 &
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -O -N -R -G -t -n 50 -m 10 -l 170 -e 127.0.0.1 -X -g -u gorst -w hero -p 12345 $@ ::1 &
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -O -N -R -G -T -n 30 -m 10 -l 170 -y -g -u gorst -w hero -p 12345 $@ ::1 &
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -O -N -R -G -T -S -k turn_client_pkey.pem -n 30 -m 10 -l 170 -y -g -u gorst -w hero -p 12345 $@ ::1 &
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -O -N -R -G -t -S -k turn_client_pkey.pem -n 30 -m 10 -l 170 -e 127.0.0.1 -X -g -u gorst -w hero -p 12345 $@ ::1 &
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -O -N -R -G -n 30 -m 10 -l 170 -g -u ninefingers -w youhavetoberealistic -y -p 12346 $@ ::1 &
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -O -N -R -G -n 30 -m 10 -l 170 -e 127.0.0.1 -X -g -u ninefingers -w youhavetoberealistic -p 12346 $@ ::1 &
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -O -N -R -G -S -k turn_client_pkey.pem -n 30 -m 10 -l 170 -e ::1 -x -g -u ninefingers -w youhavetoberealistic -s -p 12346 $@ 127.0.0.1 &
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -O -N -R -G -t -n 50 -m 10 -l 170 -e 127.0.0.1 -X -g -u gorst -w hero -p 12346 $@ ::1 &
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -O -N -R -G -T -n 30 -m 10 -l 170 -y -g -u gorst -w hero -p 12346 $@ ::1 &
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -O -N -R -G -T -S -k turn_client_pkey.pem -n 30 -m 10 -l 170 -y -g -u gorst -w hero -p 12346 $@ ::1 &
PATH=examples/bin/:../bin:./bin/:${PATH} turnutils_uclient -O -N -R -G -t -S -k turn_client_pkey.pem -n 30 -m 10 -l 170 -e 127.0.0.1 -X -g -u gorst -w hero -p 12346 $@ ::1 &
#########################
sleep ${SLEEP_TIME}
type killall >>/dev/null 2>>/dev/null
ER=$?
if [ ${ER} -eq 0 ] ; then
killall turnutils_uclient >>/dev/null 2>>/dev/null
fi
type pkill >>/dev/null 2>>/dev/null
ER=$?
if [ ${ER} -eq 0 ] ; then
pkill turnutils_u >>/dev/null 2>>/dev/null
pkill turnutils_uclie >>/dev/null 2>>/dev/null
pkill turnutils_uclient >>/dev/null 2>>/dev/null
else
sleep 10
fi
done

View File

@ -0,0 +1,42 @@
#!/bin/sh
#
# This is an example how to start a TURN Server
# with self-udp-balancing, in secure mode
# (when authentication is used) - see option -a
# that means "use long-term credential mechanism".
#
# We start here a TURN Server listening on IPv4 address
# 127.0.0.1 and on IPv6 address ::1. We use 127.0.0.1 as
# IPv4 relay address, and we use ::1 as IPv6 relay address.
#
# Other options:
#
# 1) --aux-server=... options start two auxiliary severs on IP address 127.0.0.1
# and ports 12345 and 12346, and two auxiliary servers on IP adress ::1
# with the same ports.
# 2) --self-udp-balance option forces the server to distribute the load from the
# main server points to the auxiliary servers through the ALTERNATE-SERVER
# mechanism.
# 3) set bandwidth limit on client session 3000000 bytes per second (--max-bps).
# 4) use fingerprints (-f)
# 5) use 10 relay threads (-m 10)
# 6) use min UDP relay port 32355 and max UDP relay port 65535
# 7) "-r north.gov" means "use authentication realm north.gov"
# 8) "--user=ninefingers:youhavetoberealistic" means
# "allow user 'ninefinger' with password 'youhavetoberealistic' ".
# 9) "--user=gorst:hero" means "allow user 'gorst' with password 'hero' ".
# 10) "--cert=example_turn_server_cert.pem" sets the OpenSSL certificate file name.
# 11) "--pkey=example_turn_server_pkey.pem" sets the OpenSSL private key name.
# 12) "--log-file=stdout" means that all log output will go to the stdout.
# 13) "-v" means normal verbose mode (with some moderate logging).
# 14) --cipher-list=ALL:SSLv2 means that we support all OpenSSL ciphers, including SSLv2.
# Other parameters (config file name, etc) are default.
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
PATH="./bin/:../bin/:../../bin/:${PATH}" turnserver --aux-server=127.0.0.1:12345 --aux-server=[::1]:12345 --aux-server=127.0.0.1:12346 --aux-server=[::1]:12346 --udp-self-balance --syslog -a -L 127.0.0.1 -L ::1 -E 127.0.0.1 -E ::1 --max-bps=3000000 -f -m 10 --min-port=32355 --max-port=65535 --user=ninefingers:youhavetoberealistic --user=gorst:hero -r north.gov --cert=turn_server_cert.pem --pkey=turn_server_pkey.pem --log-file=stdout --cipher-list=ALL:SSLv2 $@

View File

@ -0,0 +1,37 @@
#!/bin/sh
#
# This is an example how to start a TURN Server in
# secure mode with short-term security mechanism - see option -A
# that means "use short-term credential mechanism".
#
# The short-term credentials mechanism must be used with PostgreSQL or
# MySQL database only, the flat file userdb cannot be used.
#
# We listen on available interfaces here, and we use the "external" IPs
# for relay endpoints allocation.
#
# Other options:
#
# 1) set bandwidth limit on client session 3000000 bytes per second (--max-bps).
# 2) use fingerprints (-f)
# 3) use 3 relay threads (-m 3)
# 4) use min UDP relay port 32355 and max UDP relay port 65535
# 5) --mysql-userdb="host=localhost dbname=coturn user=turn password=turn connect_timeout=30"
# means that local MySQL database "coturn" will be used, with database user "turn" and
# database user password "turn", and connection timeout 30 seconds.
# 6) "--cert=example_turn_server_cert.pem" sets the OpenSSL certificate file name.
# 7) "--pkey=example_turn_server_pkey.pem" sets the OpenSSL private key name.
# 8) "--log-file=stdout" means that all log output will go to the stdout.
# 9) -E 127.0.0.1 and -E :;1 sets the relay addresses, in this case for loopback
# communications only.
# 10) --cipher-list=ALL:SSLv2 means that we support all OpenSSL ciphers, including SSLv2.
# Other parameters (config file name, etc) are default.
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
PATH="./bin/:../bin/:../../bin/:${PATH}" turnserver -v --syslog -A --max-bps=3000000 -f -m 3 --min-port=32355 --max-port=65535 --mysql-userdb="host=localhost dbname=coturn user=turn password=turn connect_timeout=30" --cert=turn_server_cert.pem --pkey=turn_server_pkey.pem --log-file=stdout -E 127.0.0.1 -E ::1 --cipher-list=ALL:SSLv2 $@

View File

@ -0,0 +1,31 @@
#!/bin/sh
#
# This is an example of a script to run a "secure" TURN TCP client
# with the short-term credentials mechanism and with
# TCP relay endpoints (RFC 6062).
#
# Options:
#
# 1) -T is present, it means that TCP networking is used, with TCP relay endpoints (RFC 6062).
# 5) -n 1000 means 1000 messages per single emulated client. Messages
# are sent with interval of 20 milliseconds, to emulate an RTP stream.
# 6) -m 10 means that 10 clients are emulated.
# 7) -l 170 means that the payload size of the packets is 170 bytes
# (like average audio RTP packet).
# 8) -y means that the clients will connect to the 'neighbor' clients, no peer app will be used.
# 9) -g means "set DONT_FRAGMENT parameter in TURN requests".
# 10) -A sets the short-term credentials mechanism.
# 11) -u gorst sets the client user name.
# 12) -w hero sets the password for the account as "hero".
# 13) ::1 (the last parameter) is the TURN Server IP address. We use IPv6 here
# to illustrate how the TURN Server convert the traffic from IPv6 to IPv4 and back.
#
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -T -n 1000 -m 10 -l 170 -y -g -A -u gorst -w hero $@ ::1

View File

@ -0,0 +1,30 @@
#!/bin/sh
#
# This is an example of a script to run a "secure" TURN UDP client
# with short-term credential mechanism.
#
# Options:
#
# 1) -t is absent, it means that UDP networking is used.
# 5) -n 1000 means 1000 messages per single emulated client. Messages
# are sent with interval of 20 milliseconds, to emulate an RTP stream.
# 6) -m 10 means that 10 clients are emulated.
# 7) -l 170 means that the payload size of the packets is 170 bytes
# (like average audio RTP packet).
# 8) -e 127.0.0.1 means that the clients will use peer address 127.0.0.1.
# 9) -g means "set DONT_FRAGMENT parameter in TURN requests".
# 10) -A means that the short-term credentials mechanism is used.
# 11) -u ninefingers sets the client user name.
# 12) -w youhavetoberealistic sets the password for the user account as "youhavetoberealistic".
# 13) -s option means that the client will be using "send" indication for data trasfer.
# 14) ::1 (the last parameter) is the TURN Server IP address. We use IPv6 here
# to illustrate how the TURN Server convert the traffic from IPv6 to IPv4 and back.
#
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/
PATH=examples/bin/:../bin/:./bin/:${PATH} turnutils_uclient -n 1000 -m 10 -l 170 -e 127.0.0.1 -X -g -A -u ninefingers -w youhavetoberealistic -s $@ ::1

15
make-man.sh Executable file
View File

@ -0,0 +1,15 @@
#!/bin/sh
rm -rf man/man1/*
txt2man -s 1 -t TURN -I turnserver -I turnadmin -I turnutils -I turnutils_uclient -I turnutils_stunclient -I turnutils_rfc5769check -I turnutils_peer -B "TURN Server" README.turnserver | sed -e 's/-/\\-/g' > man/man1/turnserver.1
txt2man -s 1 -t TURN -I turnserver -I turnadmin -I turnutils -I turnutils_uclient -I turnutils_stunclient -I turnutils_rfc5769check -I turnutils_peer -B "TURN Server" README.turnadmin | sed -e 's/-/\\-/g'> man/man1/turnadmin.1
txt2man -s 1 -t TURN -I turnserver -I turnadmin -I turnutils -I turnutils_uclient -I turnutils_stunclient -I turnutils_rfc5769check -I turnutils_peer -B "TURN Server" README.turnutils | sed -e 's/-/\\-/g' > man/man1/turnutils.1
cd man/man1; ln -s turnutils.1 turnutils_uclient.1;cd ../..
cd man/man1; ln -s turnutils.1 turnutils_peer.1;cd ../..
cd man/man1; ln -s turnutils.1 turnutils_stunclient.1;cd ../..
cd man/man1; ln -s turnserver.1 coturn.1;cd ../..

1
man/man1/coturn.1 Symbolic link
View File

@ -0,0 +1 @@
turnserver.1

325
man/man1/turnadmin.1 Normal file
View File

@ -0,0 +1,325 @@
.\" Text automatically generated by txt2man
.TH TURN 1 "20 April 2014" "" ""
.SH GENERAL INFORMATION
\fIturnadmin\fP is a TURN administration tool. This tool can be used to manage
the user accounts (add/remove users, generate
TURN keys for the users). For security reasons, we do not recommend
storing passwords openly. The better option is to use pre\-processed "keys"
which are then used for authentication. These keys are generated by \fIturnadmin\fP.
Turnadmin is a link to \fIturnserver\fP binary, but \fIturnadmin\fP performs different
functions.
.PP
Options note: \fIturnadmin\fP has long and short option names, for most options.
Some options have only long form, some options have only short form. Their syntax
somewhat different, if an argument is required:
.PP
The short form must be used as this (for example):
.PP
.nf
.fam C
$ turnadmin \-u <username> \.\.\.
.fam T
.fi
The long form equivalent must use the "=" character:
.PP
.nf
.fam C
$ turnadmin \-\-user=<username> \.\.\.
.fam T
.fi
If this is a flag option (no argument required) then their usage are the same, for example:
.PP
.nf
.fam C
$ turnadmin \-k \.\.\.
.fam T
.fi
is equivalent to:
.PP
.nf
.fam C
$ turnadmin \-\-key \.\.\.
.fam T
.fi
You have always the use the \fB\-r\fP <realm> option with commands for long term credentials \-
because data for multiple realms can be stored in the same database.
.PP
=====================================
.SS NAME
\fB
\fBturnadmin \fP\- a TURN relay administration tool.
\fB
.SS SYNOPSIS
$ \fIturnadmin\fP [command] [options]
.PP
$ \fIturnadmin\fP [ \fB\-h\fP | \fB\-\-help\fP]
.SS DESCRIPTION
.TP
.B
Commands:
.TP
.B
\fB\-k\fP, \fB\-\-key\fP
Generate key for a long\-term credentials mechanism user.
.TP
.B
\fB\-a\fP, \fB\-\-add\fP
Add or update a long\-term user.
.TP
.B
\fB\-A\fP, \fB\-\-add\-st\fP
Add or update a short\-term credentials mechanism user.
.TP
.B
\fB\-d\fP, \fB\-\-delete\fP
Delete a long\-term user.
.TP
.B
\fB\-D\fP, \fB\-\-delete\-st\fP
Delete a short\-term user.
.TP
.B
\fB\-l\fP, \fB\-\-list\fP
List long\-term users in the database.
.TP
.B
\fB\-L\fP, \fB\-\-list\-st\fP
List short\-term users in the database.
.PP
\fB\-s\fP, \fB\-\-set\-secret\fP=<value> Add shared secret for TURN RESP API
.TP
.B
\fB\-S\fP, \fB\-\-show\-secret\fP
Show stored shared secrets for TURN REST API
.PP
\fB\-X\fP, \fB\-\-delete\-secret\fP=<value> Delete a shared secret.
.RS
.TP
.B
\fB\-\-delete\-all_secrets\fP
Delete all shared secrets for REST API.
.RE
.TP
.B
\fB\-O\fP, \fB\-\-add\-origin\fP
Add origin\-to\-realm relation.
.TP
.B
\fB\-R\fP, \fB\-\-del\-origin\fP
Delete origin\-to\-realm relation.
.TP
.B
\fB\-I\fP, \fB\-\-list\-origins\fP
List origin\-to\-realm relations.
.TP
.B
\fB\-g\fP, \fB\-\-set\-realm\-option\fP
Set realm params: max\-bps, total\-quota, user\-quota.
.TP
.B
\fB\-G\fP, \fB\-\-list\-realm\-options\fP
List realm params.
.PP
NOTE: if you are using the flat file for the user database, then you will have
to use a text editor to set or show the shared secrets.
.PP
NOTE: the origin functionality is not supported with flat user db file,
a "real" database must be used.
.TP
.B
Options with required values:
.TP
.B
\fB\-b\fP, \fB\-\-userdb\fP
File\-based user database file name (default \- turnuserdb.conf).
See the \fB\-\-userdb\fP option in the \fIturnserver\fP section.
.TP
.B
\fB\-e\fP, \fB\-\-psql\-userdb\fP
PostgreSQL user database connection string.
See the \fB\-\-psql\-userdb\fP option in the \fIturnserver\fP section.
.TP
.B
\fB\-M\fP, \fB\-\-mysql\-userdb\fP
MySQL user database connection string.
See the \fB\-\-mysql\-userdb\fP option in the \fIturnserver\fP section.
.TP
.B
\fB\-N\fP, \fB\-\-redis\-userdb\fP
Redis user database connection string.
See the \fB\-\-redis\-userdb\fP option in the \fIturnserver\fP section.
.TP
.B
\fB\-u\fP, \fB\-\-user\fP
User name.
.TP
.B
\fB\-r\fP, \fB\-\-realm\fP
Realm, for long\-term credentials mechanism only.
.TP
.B
\fB\-p\fP, \fB\-\-password\fP
Password.
.TP
.B
\fB\-o\fP, \fB\-\-origin\fP
Origin
.TP
.B
\fB\-H\fP, \fB\-\-sha256\fP
Use SHA256 as the keys hash function (a non\-standard feature).
By default, MD5 is used for the key storage encryption
(as required by the current STUN/TURNstandards).
.TP
.B
\fB\-\-max\-bps\fP
Set value of realm's max\-bps parameter.
.TP
.B
\fB\-\-total\-quota\fP
Set value of realm's total\-quota parameter.
.TP
.B
\fB\-\-user\-quota\fP
Set value of realm's user\-quota parameter.
.TP
.B
\fB\-h\fP, \fB\-\-help\fP
Help.
.TP
.B
Generate a key:
.PP
$ \fIturnadmin\fP \fB\-k\fP \fB\-u\fP <username> \fB\-r\fP <realm> \fB\-p\fP <password>
.PP
Add/update a user in the userdb file or in the database:
.PP
$ \fIturnadmin\fP \fB\-a\fP [\fB\-b\fP <userdb\-file> | \fB\-e\fP <db\-connection\-string> | \fB\-M\fP <db\-connection\-string> | \fB\-N\fP <db\-connection\-string> ] \fB\-u\fP <username> \fB\-r\fP <realm> \fB\-p\fP <password>
.PP
Delete a user from the userdb file or from the database:
.PP
$ \fIturnadmin\fP \fB\-d\fP [\fB\-b\fP <userdb\-file> | \fB\-e\fP <db\-connection\-string> | \fB\-M\fP <db\-connection\-string> | \fB\-N\fP <db\-connection\-string> ] \fB\-u\fP <username> \fB\-r\fP <realm>
.PP
List all long\-term users in MySQL database:
.PP
$ \fIturnadmin\fP \fB\-l\fP \fB\-\-mysql\-userdb\fP="<db\-connection\-string>" \fB\-r\fP <realm>
.PP
List all short\-term users in Redis database:
.PP
$ \fIturnadmin\fP \fB\-L\fP \fB\-\-redis\-userdb\fP="<db\-connection\-string>"
.PP
Set secret in MySQL database:
.PP
$ \fIturnadmin\fP \fB\-s\fP <secret> \fB\-\-mysql\-userdb\fP="<db\-connection\-string>" \fB\-r\fP <realm>
.PP
Show secret stored in PostgreSQL database:
.PP
$ \fIturnadmin\fP \fB\-S\fP \fB\-\-psql\-userdb\fP="<db\-connection\-string>" \fB\-r\fP <realm>
.PP
Set origin\-to\-realm relation in MySQL database:
.PP
$ \fIturnadmin\fP \fB\-\-mysql\-userdb\fP="<db\-connection\-string>" \fB\-r\fP <realm> \fB\-o\fP <origin>
.PP
Delete origin\-to\-realm relation from Redis DB:
.PP
$ \fIturnadmin\fP \fB\-\-redis\-userdb\fP="<db\-connection\-string>" \fB\-o\fP <origin>
.PP
List all origin\-to\-realm relations in Redis DB:
.PP
$ \fIturnadmin\fP \fB\-\-redis\-userdb\fP="<db\-connection\-string>" \fB\-I\fP
.PP
List the origin\-to\-realm relations in PostgreSQL DB for a single realm:
.PP
$ \fIturnadmin\fP \fB\-\-psql\-userdb\fP="<db\-connection\-string>" \fB\-I\fP \fB\-r\fP <realm>
.TP
.B
Help:
.PP
$ \fIturnadmin\fP \fB\-h\fP
.PP
=======================================
.SS DOCS
After installation, run the command:
.PP
$ man \fIturnadmin\fP
.PP
or in the project root directory:
.PP
$ man \fB\-M\fP man \fIturnadmin\fP
.PP
to see the man page.
.PP
=====================================
.SS FILES
/etc/turnserver.conf
.PP
/etc/turnuserdb.conf
.PP
/usr/local/etc/turnserver.conf
.PP
/usr/local/etc/turnuserdb.conf
.PP
=====================================
.SS DIRECTORIES
/usr/local/share/\fIturnserver\fP
.PP
/usr/local/share/doc/\fIturnserver\fP
.PP
/usr/local/share/examples/\fIturnserver\fP
.PP
======================================
.SS SEE ALSO
\fIturnserver\fP, \fIturnutils\fP
.RE
.PP
======================================
.SS WEB RESOURCES
project page:
.PP
http://code.google.com/p/coturn/
.PP
Wiki page:
.PP
http://code.google.com/p/coturn/wiki/Readme
.PP
forum:
.PP
https://groups.google.com/forum/?fromgroups=#!forum/turn\-server\-project\-rfc5766\-turn\-server/
.RE
.PP
======================================
.SS AUTHORS
Oleg Moskalenko <mom040267@gmail.com>
.PP
Gabor Kovesdan http://kovesdan.org/
.PP
Daniel Pocock http://danielpocock.com/
.PP
John Selbie (jselbie@gmail.com)
.PP
Lee Sylvester <lee@designrealm.co.uk>
.PP
Erik Johnston <erikj@openmarket.com>
.PP
Roman Lisagor <roman@demonware.net>
.PP
Vladimir Tsanev <tsachev@gmail.com>
.PP
Po\-sheng Lin <personlin118@gmail.com>
.PP
Peter Dunkley <peter.dunkley@crocodilertc.net>
.PP
Mutsutoshi Yoshimoto <mutsutoshi.yoshimoto@mixi.co.jp>

1121
man/man1/turnserver.1 Normal file

File diff suppressed because it is too large Load Diff

439
man/man1/turnutils.1 Normal file
View File

@ -0,0 +1,439 @@
.\" Text automatically generated by txt2man
.TH TURN 1 "20 April 2014" "" ""
.SH GENERAL INFORMATION
A set of turnutils_* programs provides some utility functionality to be used
for testing and for setting up the TURN server.
.TP
.B
1.
\fIturnutils_uclient\fP: emulates multiple UDP,TCP,TLS or DTLS clients.
(this program is provided for the testing purposes only !)
The compiled binary image of this program is located in bin/
sub\-directory.
.PP
WARNING: the \fIturnutils_uclient\fP program is a primitive client application.
It does not implement the re\-transmission pattern that is necessary for
a correct TURN client implementation. In TURN, the retransmission burden
is lying almost entirely on the client application. We provide the messaging
functionality in the client library, but the client must implement
the correct Networking IO processing in the client program code.
.TP
.B
2.
\fIturnutils_peer\fP: a simple stateless UDP\-only "echo" server,
to be used as the final server in relay pattern ("peer"). For every incoming
UDP packet, it simply echoes it back.
(this program is provided for the testing purposes only !)
When the test clients are communicating in the client\-to\-client manner
(when the "\fIturnutils_uclient\fP" program is used with "\fB\-y\fP" option) then the
\fIturnutils_peer\fP is not needed.
.PP
The compiled binary image of this program is located in bin/ subdirectory.
.TP
.B
3.
\fIturnutils_stunclient\fP: a simple STUN client example.
The compiled binary image of this program is located in bin/ subdirectory.
.TP
.B
4.
\fIturnutils_rfc5769check\fP: a utility that checks the correctness of the
STUN/TURN protocol implementation. This utility is used only for the compilation
check procedure, it is not copied to the installation destination.
.RE
.PP
.RS
In the "examples/scripts" subdirectory, you will find the examples of command lines to be used
to run the programs. The scripts are meant to be run from examples/ subdirectory, for example:
.PP
$ cd examples
.PP
$ ./scripts/secure_relay.sh
.PP
=====================================
.SS NAME
\fB
\fBturnutils_uclient \fP\- this client emulation application is supplied for the test purposes only.
\fB
.SS SYNOPSIS
$ \fIturnutils_uclient\fP [\fB\-tTSvsyhcxg\fP] [options] <TURN\-Server\-IP\-address>
.SS DESCRIPTION
It was designed to simulate multiple clients. It uses asynch IO API in
libevent to handle multiple clients. A client connects to the relay,
negotiates the session, and sends multiple (configured number) messages to the server (relay),
expecting the same number of replies. The length of the messages is configurable.
The message is an arbitrary octet stream, but it can be configured as a string.
The number of the messages to send is configurable.
.TP
.B
Flags:
.TP
.B
\fB\-t\fP
Use TCP 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.
.TP
.B
\fB\-P\fP
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.
.TP
.B
\fB\-U\fP
Secure unencrypted connection (suite eNULL): SSL/TLS for TCP, DTLS for UDP.
.TP
.B
\fB\-v\fP
Verbose.
.TP
.B
\fB\-s\fP
Use "Send" method in TURN; by default, it uses TURN Channels.
.TP
.B
\fB\-y\fP
Use client\-to\-client connections:
RTP/RTCP pair of channels to another RTP/RTCP pair of channels.
with this option the \fIturnutils_peer\fP application is not used,
as the allocated relay endpoints are talking to each other.
.TP
.B
\fB\-h\fP
Hang on indefinitely after the last sent packet.
.TP
.B
\fB\-c\fP
Do not create rtcp connections.
.TP
.B
\fB\-x\fP
Request IPv6 relay address (RFC6156).
.TP
.B
\fB\-X\fP
IPv4 relay address explicitly requested.
.TP
.B
\fB\-g\fP
Set DONT_FRAGMENT parameter in TURN requests.
.TP
.B
\fB\-A\fP
use short\-term credentials mechanism for authentication.
By default, the program uses the long\-term credentials mechanism
if authentication is required.
.TP
.B
\fB\-D\fP
Do mandatory channel padding even for UDP (like pjnath).
.TP
.B
\fB\-N\fP
do negative tests (some limited cases only).
.TP
.B
\fB\-R\fP
do negative protocol tests.
.TP
.B
\fB\-O\fP
DOS attack mode.
.TP
.B
\fB\-H\fP
SHA256 digest function for message integrity calculation.
Without this option, by default, SHA1 is used.
.TP
.B
\fB\-M\fP
Use TURN ICE Mobility.
.TP
.B
\fB\-I\fP
Do not set permissions on TURN relay endpoints
(for testing the non\-standard server relay functionality).
.TP
.B
\fB\-G\fP
Generate extra requests (create permissions, channel bind).
.TP
.B
Options with required values:
.TP
.B
\fB\-l\fP
Message length (Default: 100 Bytes).
.TP
.B
\fB\-i\fP
Certificate file (for secure connections only, optional).
.TP
.B
\fB\-k\fP
Private key file (for secure connections only).
.TP
.B
\fB\-E\fP
CA file for server certificate verification,
if the server certificate to be verified.
.TP
.B
\fB\-p\fP
\fBTURN Server\fP port (Defaults: 3478 unsecure, 5349 secure).
.TP
.B
\fB\-n\fP
Number of messages to send (Default: 5).
.TP
.B
\fB\-d\fP
Local interface device (optional, Linux only).
.TP
.B
\fB\-L\fP
Local IP address (optional).
.TP
.B
\fB\-m\fP
Number of clients (Default: 1, 2 or 4, depending on options).
.TP
.B
\fB\-e\fP
Peer address.
.TP
.B
\fB\-r\fP
Peer port (Default: 3480).
.TP
.B
\fB\-z\fP
Per\-session packet interval in milliseconds (Default: 20).
.TP
.B
\fB\-u\fP
STUN/TURN user name.
.TP
.B
\fB\-w\fP
STUN/TURN user password.
.TP
.B
\fB\-W\fP
TURN REST API authentication secret. Is not compatible with \fB\-A\fP flag.
.TP
.B
\fB\-C\fP
This is the timestamp/username separator symbol (character) in
TURN REST API. The default value is :.
.TP
.B
\fB\-F\fP
Cipher suite for TLS/DTLS. Default value is DEFAULT.
.PP
See the examples in the "examples/scripts" directory.
.PP
======================================
.SS NAME
\fB
\fBturnutils_peer \fP\- a simple UDP\-only echo backend server.
\fB
.SS SYNOPSYS
$ \fIturnutils_peer\fP [\fB\-v\fP] [options]
.SS DESCRIPTION
This application is used for the test purposes only, as a peer for the \fIturnutils_uclient\fP application.
.TP
.B
Options with required values:
.TP
.B
\fB\-p\fP
Listening UDP port (Default: 3480).
.TP
.B
\fB\-d\fP
Listening interface device (optional)
.TP
.B
\fB\-L\fP
Listening address of \fIturnutils_peer\fP server. Multiple listening addresses can be used, IPv4 and IPv6.
If no listener \fBaddress\fP(es) defined, then it listens on all IPv4 and IPv6 addresses.
.TP
.B
\fB\-v\fP
Verbose
.PP
========================================
.SS NAME
\fB
\fBturnutils_stunclient \fP\- a basic STUN client.
\fB
.SS SYNOPSIS
.nf
.fam C
$ \fIturnutils_stunclient\fP [\fIoptions\fP] <STUN\-Server\-IP\-address>
.fam T
.fi
.fam T
.fi
.SS DESCRIPTION
It sends a "new" STUN RFC 5389 request (over UDP) and shows the reply information.
.TP
.B
Options with required values:
.TP
.B
\fB\-p\fP
STUN server port (Default: 3478).
.TP
.B
\fB\-L\fP
Local address to use (optional).
.TP
.B
\fB\-f\fP
Force RFC 5780 processing.
.PP
The \fIturnutils_stunclient\fP program checks the results of the first request,
and if it finds that the STUN server supports RFC 5780
(the binding response reveals that) then the \fIturnutils_stunclient\fP makes a couple more
requests with different parameters, to demonstrate the NAT discovery capabilities.
.PP
This utility does not support the "old" "classic" STUN protocol (RFC 3489).
.PP
=====================================
.SS NAME
\fB
\fBturnutils_rfc5769check \fP\- a utility that tests the correctness of STUN protocol implementation.
\fB
.SS SYNOPSIS
.nf
.fam C
$ \fIturnutils_rfc5769check\fP
.fam T
.fi
.fam T
.fi
.SS DESCRIPTION
\fIturnutils_rfc5769check\fP tests the correctness of STUN protocol implementation
against the test vectors predefined in RFC 5769 and prints the results of the
tests on the screen. This utility is used only for the compilation
check procedure, it is not copied to the installation destination.
.TP
.B
Usage:
.PP
$ \fIturnutils_rfc5769check\fP
.PP
===================================
.SH DOCS
After installation, run the command:
.PP
$ man \fIturnutils\fP
.PP
or in the project root directory:
.PP
$ man \fB\-M\fP man \fIturnutils\fP
.PP
to see the man page.
.PP
=====================================
.SH FILES
/etc/turnserver.conf
.PP
/etc/turnuserdb.conf
.PP
/usr/local/etc/turnserver.conf
.PP
/usr/local/etc/turnuserdb.conf
.PP
=================================
.SH DIRECTORIES
/usr/local/share/\fIturnserver\fP
.PP
/usr/local/share/doc/\fIturnserver\fP
.PP
/usr/local/share/examples/\fIturnserver\fP
.PP
===================================
.SH STANDARDS
new STUN RFC 5389
.PP
TURN RFC 5766
.PP
TURN\-TCP extension RFC 6062
.PP
TURN IPv6 extension RFC 6156
.PP
STUN/TURN test vectors RFC 5769
.PP
STUN NAT behavior discovery RFC 5780
.PP
====================================
.SH SEE ALSO
\fIturnserver\fP, \fIturnadmin\fP
.RE
.PP
======================================
.SS WEB RESOURCES
project page:
.PP
http://code.google.com/p/coturn/
.PP
Wiki page:
.PP
http://code.google.com/p/coturn/wiki/Readme
.PP
forum:
.PP
https://groups.google.com/forum/?fromgroups=#!forum/turn\-server\-project\-rfc5766\-turn\-server/
.RE
.PP
======================================
.SS AUTHORS
Oleg Moskalenko <mom040267@gmail.com>
.PP
Gabor Kovesdan http://kovesdan.org/
.PP
Daniel Pocock http://danielpocock.com/
.PP
John Selbie (jselbie@gmail.com)
.PP
Lee Sylvester <lee@designrealm.co.uk>
.PP
Erik Johnston <erikj@openmarket.com>
.PP
Roman Lisagor <roman@demonware.net>
.PP
Vladimir Tsanev <tsachev@gmail.com>
.PP
Po\-sheng Lin <personlin118@gmail.com>
.PP
Peter Dunkley <peter.dunkley@crocodilertc.net>
.PP
Mutsutoshi Yoshimoto <mutsutoshi.yoshimoto@mixi.co.jp>

1
man/man1/turnutils_peer.1 Symbolic link
View File

@ -0,0 +1 @@
turnutils.1

View File

@ -0,0 +1 @@
turnutils.1

View File

@ -0,0 +1 @@
turnutils.1

35
postinstall.txt Normal file
View File

@ -0,0 +1,35 @@
==================================================================
1) If you system supports automatic start-up system daemon services,
the, to enable the turnserver as an automatically started system
service, you have to:
a) Create and edit /etc/turnserver.conf or
/usr/local/etc/turnserver.conf .
Use /usr/local/etc/turnserver.conf.default as an example.
b) For user accounts settings, if using the turnserver
with authentication: create and edit /etc/turnuserdb.conf
file, or set up PostgreSQL or MySQL or Redis database for user accounts.
Use /usr/local/etc/turnuserdb.conf.default as example for flat file DB,
or use /usr/local/share/turnserver/schema.sql as SQL database schema,
or use /usr/local/share/turnserver/schema.userdb.redis as Redis
database schema description and/or /usr/local/share/turnserver/schema.stats.redis
as Redis status & statistics database schema description.
c) add whatever is necessary to enable start-up daemon for the /usr/local/bin/turnserver.
2) If you do not want the turnserver to be a system service,
then you can start/stop it "manually", using the "turnserver"
executable with appropriate options (see the documentation).
3) To create database schema, use schema in file /usr/local/share/turnserver/schema.sql.
4) For additional information, run:
$ man turnserver
$ man turnadmin
$ man turnutils
==================================================================

98
rpm/CentOS6.pre.build.sh Executable file
View File

@ -0,0 +1,98 @@
#!/bin/bash
# CentOS6 preparation script.
CPWD=`pwd`
. ./common.pre.build.sh
cd ${CPWD}
EPELRPM=epel-release-6-8.noarch.rpm
LIBEVENT_MAJOR_VERSION=2
LIBEVENT_VERSION=${LIBEVENT_MAJOR_VERSION}.0.21
LIBEVENT_DISTRO=libevent-${LIBEVENT_VERSION}-stable.tar.gz
LIBEVENT_SPEC_DIR=libevent.rpm
LIBEVENTSPEC_SVN_URL=${TURNSERVER_SVN_URL}/${LIBEVENT_SPEC_DIR}
LIBEVENT_SPEC_FILE=libevent.spec
# Common packs
PACKS="mysql-devel"
sudo yum -y install ${PACKS}
ER=$?
if ! [ ${ER} -eq 0 ] ; then
echo "Cannot install package(s) ${PACKS}"
cd ${CPWD}
exit -1
fi
# Libevent2:
cd ${BUILDDIR}/SOURCES
if ! [ -f ${LIBEVENT_DISTRO} ] ; then
wget ${WGETOPTIONS} https://github.com/downloads/libevent/libevent/${LIBEVENT_DISTRO}
ER=$?
if ! [ ${ER} -eq 0 ] ; then
cd ${CPWD}
exit -1
fi
fi
if ! [ -f ${BUILDDIR}/SPECS/${LIBEVENT_SPEC_FILE} ] ; then
cd ${BUILDDIR}/tmp
rm -rf ${LIBEVENT_SPEC_DIR}
svn export ${LIBEVENTSPEC_SVN_URL} ${LIBEVENT_SPEC_DIR}
ER=$?
if ! [ ${ER} -eq 0 ] ; then
cd ${CPWD}
exit -1
fi
if ! [ -f ${LIBEVENT_SPEC_DIR}/${LIBEVENT_SPEC_FILE} ] ; then
echo "ERROR: cannot download ${LIBEVENT_SPEC_FILE} file"
cd ${CPWD}
exit -1
fi
cp ${LIBEVENT_SPEC_DIR}/${LIBEVENT_SPEC_FILE} ${BUILDDIR}/SPECS
fi
cd ${BUILDDIR}/SPECS
rpmbuild -ba ${BUILDDIR}/SPECS/${LIBEVENT_SPEC_FILE}
ER=$?
if ! [ ${ER} -eq 0 ] ; then
cd ${CPWD}
exit -1
fi
PACK=${BUILDDIR}/RPMS/${ARCH}/libevent-${LIBEVENT_MAJOR_VERSION}*.rpm
sudo rpm ${RPMOPTIONS} ${PACK}
ER=$?
if ! [ ${ER} -eq 0 ] ; then
echo "Cannot install packages ${PACK}"
cd ${CPWD}
exit -1
fi
PACK=${BUILDDIR}/RPMS/${ARCH}/libevent-devel*.rpm
sudo rpm ${RPMOPTIONS} ${PACK}
ER=$?
if ! [ ${ER} -eq 0 ] ; then
echo "Cannot install packages ${PACK}"
cd ${CPWD}
exit -1
fi
# EPEL (for hiredis)
cd ${CPWD}
./epel.install.sh
# Platform file
echo "CentOS6.5" > ${BUILDDIR}/platform
cp ${CPWD}/epel.install.sh ${BUILDDIR}/install.sh
cd ${CPWD}

20
rpm/Fedora.pre.build.sh Executable file
View File

@ -0,0 +1,20 @@
#!/bin/bash
CPWD=`pwd`
# Fedora preparation script.
. ./common.pre.build.sh
PACKS="libevent-devel mariadb-devel"
sudo yum -y install ${PACKS}
ER=$?
if ! [ ${ER} -eq 0 ] ; then
echo "Cannot install package(s) ${PACKS}"
cd ${CPWD}
exit -1
fi
echo "Fedora20" > ${BUILDDIR}/platform
cd ${CPWD}

View File

@ -0,0 +1,43 @@
MANUAL PROCESS FOR CENTOS 6:
The first thing you need to build/use the TURN server with CentOS is to build and install libevent 2.x.x. CentOS 6 ships with libevent 1.x.x. You can find a .spec file to build libevent 2.x.x here: https://github.com/crocodilertc/libevent
To build libevent:
1) Install the dependencies for building libevent: gcc, make, redhat-rpm-config, doxygen, openssl-devel, rpm-build
2) $ mkdir ~/rpmbuild
3) $ mkdir ~/rpmbuild/SOURCES
4) $ mkdir ~/rpmbuild/SPECS
5) Put the tarball for libevent (https://github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz) and put it into ~/rpmbuild/SOURCES
6) Put the .spec for libevent (https://raw.github.com/crocodilertc/libevent/master/libevent.spec) into ~/rpmbuild/SPECS
7) Build the RPMs, "rpmbuild -ba ~/rpmbuild/SPECS/libevent.spec"
To build the TURN server:
1) Install libevent and libevent-devel rpms
2) Install EPEL (http://fedoraproject.org/wiki/EPEL) - needed for hiredis
3) Install the dependencies for building the TURN server: gcc, make, redhat-rpm-config, openssl-devel, libevent-devel >= 2.0.0,
mysql-devel, postgresql-devel, hiredis-devel
4) $ mkdir ~/rpmbuild
5) $ mkdir ~/rpmbuild/SOURCES
6) Export the TURN server from SVN, "svn export http://coturn.googlecode.com/svn/trunk/ turnserver-2.6.7.0"
7) Create a tarball, "tar zcf ~/rpmbuild/SOURCES/turnserver-2.6.7.0.tar.gz turnserver-2.6.7.0"
8) Build the RPMs, "rpmbuild -ta ~/rpmbuild/SOURCES/turnserver-2.6.7.0.tar.gz"
AUTOMATED PROCESS FOR CENTOS 6:
$ cd <...>/coturn/rpm
$ ./CentOS6.pre.build.sh
$ ./build.sh
(then see the tarball in ~/rpmbuild/RPMS/<arch>)
AUTOMATED PROCESS FOR Fedora:
$ cd <...>/coturn/rpm
$ ./Fedora.pre.build.sh
$ ./build.sh
(then see the tarball in ~/rpmbuild/RPMS/<arch>)

14
rpm/build.settings.sh Executable file
View File

@ -0,0 +1,14 @@
#!/bin/bash
# Common settings script.
TURNVERSION=3.3.0.0
BUILDDIR=~/rpmbuild
ARCH=`uname -p`
TURNSERVER_SVN_URL=http://coturn.googlecode.com/svn
TURNSERVER_SVN_URL_VER=trunk
WGETOPTIONS="--no-check-certificate"
RPMOPTIONS="-ivh --force"

98
rpm/build.sh Executable file
View File

@ -0,0 +1,98 @@
#!/bin/bash
CPWD=`pwd`
. ./build.settings.sh
# Required packages
PACKS="postgresql-devel hiredis-devel"
sudo yum -y install ${PACKS}
ER=$?
if ! [ ${ER} -eq 0 ] ; then
echo "Cannot install packages ${PACKS}"
cd ${CPWD}
exit -1
fi
# TURN
cd ${BUILDDIR}/tmp
rm -rf turnserver-${TURNVERSION}
svn export ${TURNSERVER_SVN_URL}/${TURNSERVER_SVN_URL_VER}/ turnserver-${TURNVERSION}
ER=$?
if ! [ ${ER} -eq 0 ] ; then
cd ${CPWD}
exit -1
fi
tar zcf ${BUILDDIR}/SOURCES/turnserver-${TURNVERSION}.tar.gz turnserver-${TURNVERSION}
ER=$?
if ! [ ${ER} -eq 0 ] ; then
cd ${CPWD}
exit -1
fi
rpmbuild -ta ${BUILDDIR}/SOURCES/turnserver-${TURNVERSION}.tar.gz
ER=$?
if ! [ ${ER} -eq 0 ] ; then
cd ${CPWD}
exit -1
fi
# Make binary tarball
cd ${BUILDDIR}/RPMS/${ARCH}
mkdir -p di
mv *debuginfo* di
mv *devel* di
rm -rf turnserver-${TURNVERSION}
mkdir turnserver-${TURNVERSION}
mv *.rpm turnserver-${TURNVERSION}/
rm -rf turnserver-${TURNVERSION}/install.sh
if [ -f ${BUILDDIR}/install.sh ] ; then
cat ${BUILDDIR}/install.sh > turnserver-${TURNVERSION}/install.sh
else
echo "#!/bin/sh" > turnserver-${TURNVERSION}/install.sh
fi
cat <<EOF >>turnserver-${TURNVERSION}/install.sh
sudo yum -y install openssl
sudo yum -y install telnet
for i in *.rpm ; do
sudo yum -y install \${i}
ER=\$?
if ! [ \${ER} -eq 0 ] ; then
sudo rpm -Uvh \${i}
ER=\$?
if ! [ \${ER} -eq 0 ] ; then
sudo rpm -ivh --force \${i}
ER=\$?
if ! [ \${ER} -eq 0 ] ; then
echo "ERROR: cannot install package \${i}"
exit -1
fi
fi
fi
done
echo SUCCESS !
EOF
chmod a+x turnserver-${TURNVERSION}/install.sh
cp ${CPWD}/uninstall.turnserver.sh turnserver-${TURNVERSION}/
chmod a+x turnserver-${TURNVERSION}/uninstall.turnserver.sh
PLATFORM=`cat ${BUILDDIR}/platform`
tar cvfz turnserver-${TURNVERSION}-${PLATFORM}-${ARCH}.tar.gz turnserver-${TURNVERSION}
cd ${CPWD}

26
rpm/common.pre.build.sh Executable file
View File

@ -0,0 +1,26 @@
#!/bin/bash
# Common preparation script.
. ./build.settings.sh
# DIRS
rm -rf ${BUILDDIR}
mkdir -p ${BUILDDIR}
mkdir -p ${BUILDDIR}/SOURCES
mkdir -p ${BUILDDIR}/SPECS
mkdir -p ${BUILDDIR}/RPMS
mkdir -p ${BUILDDIR}/tmp
# Common packs
PACKS="make gcc redhat-rpm-config rpm-build doxygen openssl-devel svn"
sudo yum -y install ${PACKS}
ER=$?
if ! [ ${ER} -eq 0 ] ; then
echo "Cannot install packages ${PACKS}"
exit -1
fi

39
rpm/epel.install.sh Executable file
View File

@ -0,0 +1,39 @@
#!/bin/bash
CPWD=`pwd`
# Epel installation script
EPEL=epel-release-6-8.noarch
EPELRPM=${EPEL}.rpm
BUILDDIR=~/rpmbuild
WGETOPTIONS="--no-check-certificate"
RPMOPTIONS="-ivh --force"
mkdir -p ${BUILDDIR}
mkdir -p ${BUILDDIR}/RPMS
sudo yum -y install wget
cd ${BUILDDIR}/RPMS
if ! [ -f ${EPELRPM} ] ; then
wget ${WGETOPTIONS} http://download.fedoraproject.org/pub/epel/6/i386/${EPELRPM}
ER=$?
if ! [ ${ER} -eq 0 ] ; then
cd ${CPWD}
exit -1
fi
fi
PACK=${EPELRPM}
sudo rpm ${RPMOPTIONS} ${PACK}
ER=$?
if ! [ ${ER} -eq 0 ] ; then
echo "Cannot install package ${PACK}"
cd ${CPWD}
exit -1
fi
cd ${CPWD}

82
rpm/turnserver.init.el Normal file
View File

@ -0,0 +1,82 @@
#!/bin/bash
#
# Startup script for TURN Server
#
# chkconfig: 345 85 15
# description: RFC 5766 TURN Server
#
# processname: turnserver
# pidfile: /var/run/turnserver.pid
# config: /etc/turnserver/turnserver.conf
#
### BEGIN INIT INFO
# Provides: turnserver
# Required-Start: $local_fs $network
# Short-Description: RFC 5766 TURN Server
# Description: RFC 5766 TURN Server
### END INIT INFO
# Source function library.
. /etc/rc.d/init.d/functions
TURN=/usr/bin/turnserver
PROG=turnserver
TURNCFG=/etc/turnserver/$PROG.conf
PID_FILE=/var/run/$PROG.pid
LOCK_FILE=/var/lock/subsys/$PROG
DEFAULTS=/etc/sysconfig/$PROG
RETVAL=0
USER=turnserver
start() {
echo -n $"Starting $PROG: "
daemon --user=$USER $TURN $OPTIONS
RETVAL=$?
if [ $RETVAL = 0 ]; then
pidofproc $TURN > $PID_FILE
RETVAL=$?
[ $RETVAL = 0 ] && touch $LOCK_FILE && success
fi
echo
return $RETVAL
}
stop() {
echo -n $"Stopping $PROG: "
killproc $TURN
RETVAL=$?
echo
[ $RETVAL = 0 ] && rm -f $LOCK_FILE $PID_FILE
}
[ -f $DEFAULTS ] && . $DEFAULTS
OPTIONS="-o -c $TURNCFG $EXTRA_OPTIONS"
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status $TURN
RETVAL=$?
;;
restart)
stop
start
;;
condrestart)
if [ -f $PID_FILE ] ; then
stop
start
fi
;;
*)
echo $"Usage: $PROG {start|stop|restart|condrestart|status|help}"
exit 1
esac
exit $RETVAL

15
rpm/turnserver.service.fc Normal file
View File

@ -0,0 +1,15 @@
[Unit]
Description=coturn
Documentation=man:coturn(1) man:turnadmin(1) man:turnserver(1)
After=syslog.target network.target
[Service]
Type=forking
EnvironmentFile=/etc/sysconfig/turnserver
PIDFile=/var/run/turnserver.pid
ExecStart=/usr/bin/turnserver -o -c /etc/turnserver/turnserver.conf $EXTRA_OPTIONS
ExecStopPost=/usr/bin/rm -f /var/run/turnserver.pid
Restart=on-abort
[Install]
WantedBy=multi-user.target

358
rpm/turnserver.spec Normal file
View File

@ -0,0 +1,358 @@
Name: turnserver
Version: 3.3.0.0
Release: 0%{dist}
Summary: Coturn TURN Server
Group: System Environment/Libraries
License: BSD
URL: https://code.google.com/p/coturn/
Source0: http://turnserver.open-sys.org/downloads/v%{version}/%{name}-%{version}.tar.gz
BuildRequires: gcc, make, redhat-rpm-config
BuildRequires: openssl-devel, libevent-devel >= 2.0.0, postgresql-devel
BuildRequires: hiredis-devel
Requires: openssl, libevent >= 2.0.0, mysql-libs, postgresql-libs
Requires: hiredis, perl-DBI, perl-libwww-perl
Requires: telnet
%if 0%{?el6}
BuildRequires: epel-release, mysql-devel
Requires: epel-release, mysql-libs
%else
BuildRequires: mariadb-devel
Requires: mariadb-libs
%endif
%description
The TURN Server is a VoIP media traffic NAT traversal server and gateway. It
can be used as a general-purpose network traffic TURN server/gateway, too.
This implementation also includes some extra features. Supported RFCs:
TURN specs:
- RFC 5766 - base TURN specs
- RFC 6062 - TCP relaying TURN extension
- RFC 6156 - IPv6 extension for TURN
- Experimental DTLS support as client protocol.
STUN specs:
- RFC 3489 - "classic" STUN
- RFC 5389 - base "new" STUN specs
- RFC 5769 - test vectors for STUN protocol testing
- RFC 5780 - NAT behavior discovery support
The implementation fully supports the following client-to-TURN-server protocols:
- UDP (per RFC 5766)
- TCP (per RFC 5766 and RFC 6062)
- TLS (per RFC 5766 and RFC 6062); SSL3/TLS1.0/TLS1.1/TLS1.2; SSL2 wrapping
supported
- DTLS (experimental non-standard feature)
Supported relay protocols:
- UDP (per RFC 5766)
- TCP (per RFC 6062)
Supported user databases (for user repository, with passwords or keys, if
authentication is required):
- Flat files
- MySQL
- PostgreSQL
- Redis
Redis can also be used for status and statistics storage and notification.
Supported TURN authentication mechanisms:
- short-term
- long-term
- TURN REST API (a modification of the long-term mechanism, for time-limited
secret-based authentication, for WebRTC applications)
The load balancing can be implemented with the following tools (either one or a
combination of them):
- network load-balancer server
- DNS-based load balancing
- built-in ALTERNATE-SERVER mechanism.
%package utils
Summary: TURN client utils
Group: System Environment/Libraries
Requires: turnserver-client-libs = %{version}-%{release}
%description utils
This package contains the TURN client utils.
%package client-libs
Summary: TURN client library
Group: System Environment/Libraries
Requires: openssl, libevent >= 2.0.0
%description client-libs
This package contains the TURN client library.
%package client-devel
Summary: TURN client development headers.
Group: Development/Libraries
Requires: turnserver-client-libs = %{version}-%{release}
%description client-devel
This package contains the TURN client development headers.
%prep
%setup -q -n %{name}-%{version}
%build
PREFIX=%{_prefix} CONFDIR=%{_sysconfdir}/%{name} EXAMPLESDIR=%{_datadir}/%{name} \
MANPREFIX=%{_datadir} LIBDIR=%{_libdir} MORECMD=cat ./configure
make
%install
rm -rf $RPM_BUILD_ROOT
DESTDIR=$RPM_BUILD_ROOT make install
mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig
install -m644 rpm/turnserver.sysconfig \
$RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig/turnserver
mv $RPM_BUILD_ROOT/%{_sysconfdir}/%{name}/turnuserdb.conf.default \
$RPM_BUILD_ROOT/%{_sysconfdir}/%{name}/turnuserdb.conf
%if 0%{?el6}
cat $RPM_BUILD_ROOT/%{_sysconfdir}/%{name}/turnserver.conf.default | \
sed s/#syslog/syslog/g | \
sed s/#no-stdout-log/no-stdout-log/g > \
$RPM_BUILD_ROOT/%{_sysconfdir}/%{name}/turnserver.conf
mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/rc.d/init.d
install -m755 rpm/turnserver.init.el \
$RPM_BUILD_ROOT/%{_sysconfdir}/rc.d/init.d/turnserver
%else
cat $RPM_BUILD_ROOT/%{_sysconfdir}/%{name}/turnserver.conf.default | \
sed s/#syslog/syslog/g | \
sed s/#no-stdout-log/no-stdout-log/g | \
sed s/#pidfile/pidfile/g > \
$RPM_BUILD_ROOT/%{_sysconfdir}/%{name}/turnserver.conf
mkdir -p $RPM_BUILD_ROOT/%{_unitdir}
install -m755 rpm/turnserver.service.fc \
$RPM_BUILD_ROOT/%{_unitdir}/turnserver.service
%endif
rm -rf $RPM_BUILD_ROOT/%{_sysconfdir}/%{name}/turnserver.conf.default
%clean
rm -rf "$RPM_BUILD_ROOT"
%pre
%{_sbindir}/groupadd -r turnserver 2> /dev/null || :
%{_sbindir}/useradd -r -g turnserver -s /bin/false -c "TURN Server daemon" -d \
%{_datadir}/%{name} turnserver 2> /dev/null || :
%post
%if 0%{?el6}
/sbin/chkconfig --add turnserver
%else
/bin/systemctl --system daemon-reload
%endif
%preun
if [ $1 = 0 ]; then
%if 0%{?el6}
/sbin/service turnserver stop > /dev/null 2>&1
/sbin/chkconfig --del turnserver
%else
/bin/systemctl stop turnserver.service
/bin/systemctl disable turnserver.service 2> /dev/null
%endif
fi
%postun
%if 0%{?fedora}
/bin/systemctl --system daemon-reload
%endif
%files
%defattr(-,root,root)
%{_bindir}/turnserver
%{_bindir}/turnadmin
%{_mandir}/man1/coturn.1.gz
%{_mandir}/man1/turnserver.1.gz
%{_mandir}/man1/turnadmin.1.gz
%dir %attr(-,turnserver,turnserver) %{_sysconfdir}/%{name}
%config(noreplace) %attr(0644,turnserver,turnserver) %{_sysconfdir}/%{name}/turnserver.conf
%config(noreplace) %attr(0644,turnserver,turnserver) %{_sysconfdir}/%{name}/turnuserdb.conf
%config(noreplace) %{_sysconfdir}/sysconfig/turnserver
%if 0%{?el6}
%config %{_sysconfdir}/rc.d/init.d/turnserver
%else
%config %{_unitdir}/turnserver.service
%endif
%dir %{_docdir}/%{name}
%{_docdir}/%{name}/LICENSE
%{_docdir}/%{name}/INSTALL
%{_docdir}/%{name}/postinstall.txt
%{_docdir}/%{name}/README.turnadmin
%{_docdir}/%{name}/README.turnserver
%{_docdir}/%{name}/schema.sql
%{_docdir}/%{name}/schema.stats.redis
%{_docdir}/%{name}/schema.userdb.redis
%dir %{_datadir}/%{name}
%{_datadir}/%{name}/schema.sql
%{_datadir}/%{name}/schema.stats.redis
%{_datadir}/%{name}/schema.userdb.redis
%{_datadir}/%{name}/testredisdbsetup.sh
%{_datadir}/%{name}/testsqldbsetup.sql
%dir %{_datadir}/%{name}/etc
%{_datadir}/%{name}/etc/turn_server_cert.pem
%{_datadir}/%{name}/etc/turn_server_pkey.pem
%{_datadir}/%{name}/etc/turnserver.conf
%{_datadir}/%{name}/etc/turnuserdb.conf
%dir %{_datadir}/%{name}/scripts
%{_datadir}/%{name}/scripts/peer.sh
%{_datadir}/%{name}/scripts/readme.txt
%dir %{_datadir}/%{name}/scripts/basic
%{_datadir}/%{name}/scripts/basic/dos_attack.sh
%{_datadir}/%{name}/scripts/basic/relay.sh
%{_datadir}/%{name}/scripts/basic/tcp_client.sh
%{_datadir}/%{name}/scripts/basic/tcp_client_c2c_tcp_relay.sh
%{_datadir}/%{name}/scripts/basic/udp_c2c_client.sh
%{_datadir}/%{name}/scripts/basic/udp_client.sh
%dir %{_datadir}/%{name}/scripts/loadbalance
%{_datadir}/%{name}/scripts/loadbalance/master_relay.sh
%{_datadir}/%{name}/scripts/loadbalance/slave_relay_1.sh
%{_datadir}/%{name}/scripts/loadbalance/slave_relay_2.sh
%{_datadir}/%{name}/scripts/loadbalance/tcp_c2c_tcp_relay.sh
%{_datadir}/%{name}/scripts/loadbalance/udp_c2c.sh
%dir %{_datadir}/%{name}/scripts/longtermsecure
%{_datadir}/%{name}/scripts/longtermsecure/secure_dos_attack.sh
%{_datadir}/%{name}/scripts/longtermsecure/secure_dtls_client.sh
%{_datadir}/%{name}/scripts/longtermsecure/secure_dtls_client_cert.sh
%{_datadir}/%{name}/scripts/longtermsecure/secure_tls_client_cert.sh
%{_datadir}/%{name}/scripts/longtermsecure/secure_relay.sh
%{_datadir}/%{name}/scripts/longtermsecure/secure_relay_cert.sh
%{_datadir}/%{name}/scripts/longtermsecure/secure_tcp_client.sh
%{_datadir}/%{name}/scripts/longtermsecure/secure_tcp_client_c2c_tcp_relay.sh
%{_datadir}/%{name}/scripts/longtermsecure/secure_tls_client.sh
%{_datadir}/%{name}/scripts/longtermsecure/secure_tls_client_c2c_tcp_relay.sh
%{_datadir}/%{name}/scripts/longtermsecure/secure_udp_c2c.sh
%{_datadir}/%{name}/scripts/longtermsecure/secure_udp_client.sh
%dir %{_datadir}/%{name}/scripts/longtermsecuredb
%{_datadir}/%{name}/scripts/longtermsecuredb/secure_relay_with_db_mysql.sh
%{_datadir}/%{name}/scripts/longtermsecuredb/secure_relay_with_db_psql.sh
%{_datadir}/%{name}/scripts/longtermsecuredb/secure_relay_with_db_redis.sh
%dir %{_datadir}/%{name}/scripts/restapi
%{_datadir}/%{name}/scripts/restapi/secure_relay_secret.sh
%{_datadir}/%{name}/scripts/restapi/secure_relay_secret_with_db_mysql.sh
%{_datadir}/%{name}/scripts/restapi/secure_relay_secret_with_db_psql.sh
%{_datadir}/%{name}/scripts/restapi/secure_relay_secret_with_db_redis.sh
%{_datadir}/%{name}/scripts/restapi/secure_udp_client_with_secret.sh
%{_datadir}/%{name}/scripts/restapi/shared_secret_maintainer.pl
%dir %{_datadir}/%{name}/scripts/selfloadbalance
%{_datadir}/%{name}/scripts/selfloadbalance/secure_dos_attack.sh
%{_datadir}/%{name}/scripts/selfloadbalance/secure_relay.sh
%dir %{_datadir}/%{name}/scripts/shorttermsecure
%{_datadir}/%{name}/scripts/shorttermsecure/secure_relay_short_term_mech.sh
%{_datadir}/%{name}/scripts/shorttermsecure/secure_tcp_client_c2c_tcp_relay_short_term.sh
%{_datadir}/%{name}/scripts/shorttermsecure/secure_udp_client_short_term.sh
%dir %{_datadir}/%{name}/scripts/mobile
%{_datadir}/%{name}/scripts/mobile/mobile_relay.sh
%{_datadir}/%{name}/scripts/mobile/mobile_dtls_client.sh
%{_datadir}/%{name}/scripts/mobile/mobile_tcp_client.sh
%{_datadir}/%{name}/scripts/mobile/mobile_tls_client_c2c_tcp_relay.sh
%{_datadir}/%{name}/scripts/mobile/mobile_udp_client.sh
%files utils
%defattr(-,root,root)
%{_bindir}/turnutils_peer
%{_bindir}/turnutils_stunclient
%{_bindir}/turnutils_uclient
%{_mandir}/man1/turnutils.1.gz
%{_mandir}/man1/turnutils_peer.1.gz
%{_mandir}/man1/turnutils_stunclient.1.gz
%{_mandir}/man1/turnutils_uclient.1.gz
%dir %{_docdir}/%{name}
%{_docdir}/%{name}/LICENSE
%{_docdir}/%{name}/README.turnutils
%dir %{_datadir}/%{name}
%dir %{_datadir}/%{name}/etc
%{_datadir}/%{name}/etc/turn_client_cert.pem
%{_datadir}/%{name}/etc/turn_client_pkey.pem
%files client-libs
%{_docdir}/%{name}/LICENSE
%{_libdir}/libturnclient.a
%files client-devel
%{_docdir}/%{name}/LICENSE
%dir %{_includedir}/turn
%{_includedir}/turn/ns_turn_defs.h
%dir %{_includedir}/turn/client
%{_includedir}/turn/client/ns_turn_ioaddr.h
%{_includedir}/turn/client/ns_turn_msg_addr.h
%{_includedir}/turn/client/ns_turn_msg_defs.h
%{_includedir}/turn/client/ns_turn_msg.h
%{_includedir}/turn/client/TurnMsgLib.h
%changelog
* Sun Feb 09 2014 Oleg Moskalenko <mom040267@gmail.com>
- Sync to 3.3.0.0
* Tue Feb 04 2014 Oleg Moskalenko <mom040267@gmail.com>
- Sync to 3.2.2.6
* Sat Jan 25 2014 Oleg Moskalenko <mom040267@gmail.com>
- Sync to 3.2.2.5
* Fri Jan 24 2014 Oleg Moskalenko <mom040267@gmail.com>
- Sync to 3.2.2.4
* Thu Jan 23 2014 Oleg Moskalenko <mom040267@gmail.com>
- Sync to 3.2.2.3
* Tue Jan 21 2014 Oleg Moskalenko <mom040267@gmail.com>
- Sync to 3.2.2.2
* Sat Jan 11 2014 Oleg Moskalenko <mom040267@gmail.com>
- CPU optimization, added to 3.2.2.1
* Mon Jan 06 2014 Oleg Moskalenko <mom040267@gmail.com>
- Linux epoll performance improvements, added to 3.2.1.4
* Mon Jan 06 2014 Oleg Moskalenko <mom040267@gmail.com>
- Telnet client installation added to 3.2.1.3
* Sun Jan 05 2014 Oleg Moskalenko <mom040267@gmail.com>
- Sync to 3.2.1.2
* Fri Jan 03 2014 Oleg Moskalenko <mom040267@gmail.com>
- Sync to 3.2.1.1
* Thu Dec 26 2013 Oleg Moskalenko <mom040267@gmail.com>
- Sync to 3.2.1.0
* Wed Dec 25 2013 Oleg Moskalenko <mom040267@gmail.com>
- Sync to 3.1.6.0
* Mon Dec 23 2013 Oleg Moskalenko <mom040267@gmail.com>
- Sync to 3.1.5.3
* Fri Dec 20 2013 Oleg Moskalenko <mom040267@gmail.com>
- Sync to 3.1.5.1
* Thu Dec 19 2013 Oleg Moskalenko <mom040267@gmail.com>
- Sync to 3.1.4.2
* Sat Dec 14 2013 Oleg Moskalenko <mom040267@gmail.com>
- Sync to 3.1.3.1
* Wed Dec 11 2013 Oleg Moskalenko <mom040267@gmail.com>
- OpenSSL installation fixed 3.1.2.3
* Tue Dec 10 2013 Oleg Moskalenko <mom040267@gmail.com>
- Updated to version 3.1.2.2
* Mon Dec 09 2013 Oleg Moskalenko <mom040267@gmail.com>
- Updated to version 3.1.2.1
* Sun Dec 01 2013 Oleg Moskalenko <mom040267@gmail.com>
- Updated to version 3.1.1.0
* Sat Nov 30 2013 Oleg Moskalenko <mom040267@gmail.com>
- Updated to version 3.0.2.1.
* Thu Nov 28 2013 Oleg Moskalenko <mom040267@gmail.com>
- Config file setting fixed: version 3.0.1.4.
* Wed Nov 27 2013 Oleg Moskalenko <mom040267@gmail.com>
- Config file setting fixed: version 3.0.1.3.
* Mon Nov 25 2013 Oleg Moskalenko <mom040267@gmail.com>
- Updated to version 3.0.1.2
* Sun Nov 10 2013 Oleg Moskalenko <mom040267@gmail.com>
- Updated to version 3.0.0.0
* Fri Nov 8 2013 Oleg Moskalenko <mom040267@gmail.com>
- Updated to version 2.6.7.2
* Thu Nov 7 2013 Oleg Moskalenko <mom040267@gmail.com>
- Updated to version 2.6.7.1
* Sun Nov 3 2013 Oleg Moskalenko <mom040267@gmail.com>
- Updated to version 2.6.7.0
* Sat Nov 2 2013 Peter Dunkley <peter.dunkley@crocodilertc.net>
- Added Fedora support
* Thu Oct 31 2013 Oleg Moskalenko <mom040267@gmail.com>
- Updated to version 2.6.6.2
* Sun Oct 27 2013 Oleg Moskalenko <mom040267@gmail.com>
- Updated to version 2.6.6.1
* Sun Oct 27 2013 Peter Dunkley <peter.dunkley@crocodilertc.net>
- Updated to version 2.6.6.0
* Fri May 3 2013 Peter Dunkley <peter.dunkley@crocodilertc.net>
- First version

5
rpm/turnserver.sysconfig Normal file
View File

@ -0,0 +1,5 @@
#
# TURN Server startup options
#
EXTRA_OPTIONS=""

19
rpm/uninstall.turnserver.sh Executable file
View File

@ -0,0 +1,19 @@
#!/bin/sh
for i in `rpm -q -a | grep turnserver-utils-3`
do
echo $i
sudo rpm -e $i
done
for i in `rpm -q -a | grep turnserver-client-libs-3`
do
echo $i
sudo rpm -e $i
done
for i in `rpm -q -a | grep turnserver.*-3`
do
echo $i
sudo rpm -e $i
done

902
src/apps/common/apputils.c Normal file
View File

@ -0,0 +1,902 @@
/*
* Copyright (C) 2011, 2012, 2013 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 "ns_turn_utils.h"
#include "ns_turn_msg.h"
#include "apputils.h"
#include <event2/event.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <limits.h>
#include <ifaddrs.h>
#include <getopt.h>
#include <locale.h>
#include <libgen.h>
#include <fcntl.h>
#include <pthread.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/resource.h>
/************************/
int IS_TURN_SERVER = 0;
/*********************** Sockets *********************************/
int socket_set_nonblocking(evutil_socket_t fd)
{
#if defined(WIN32)
unsigned long nonblocking = 1;
ioctlsocket(fd, FIONBIO, (unsigned long*) &nonblocking);
#else
if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
perror("O_NONBLOCK");
return -1;
}
#endif
return 0;
}
void read_spare_buffer(evutil_socket_t fd)
{
if(fd >= 0) {
static char buffer[65536];
recv(fd, buffer, sizeof(buffer), MSG_DONTWAIT);
}
}
int set_sock_buf_size(evutil_socket_t fd, int sz0)
{
int sz;
sz = sz0;
while (sz > 0) {
if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (const void*) (&sz), (socklen_t) sizeof(sz)) < 0) {
sz = sz / 2;
} else {
break;
}
}
if (sz < 1) {
perror("Cannot set socket rcv size");
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Cannot set rcv sock size %d on fd %d\n", sz0, fd);
}
sz = sz0;
while (sz > 0) {
if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void*) (&sz), (socklen_t) sizeof(sz)) < 0) {
sz = sz / 2;
} else {
break;
}
}
if (sz < 1) {
perror("Cannot set socket snd size");
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Cannot set snd sock size %d on fd %d\n", sz0, fd);
}
return 0;
}
int socket_tcp_set_keepalive(evutil_socket_t fd)
{
#ifdef SO_KEEPALIVE
/* Set the keepalive option active */
{
int on = 1;
setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (const void*)&on, (socklen_t) sizeof(on));
}
#else
UNUSED_ARG(fd);
#endif
#ifdef SO_NOSIGPIPE
{
int on = 1;
setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (const void*)&on, (socklen_t) sizeof(on));
}
#endif
return 0;
}
int socket_set_reusable(evutil_socket_t fd, int flag)
{
if (fd < 0)
return -1;
else {
#if defined(WIN32)
int use_reuseaddr = IS_TURN_SERVER;
#else
int use_reuseaddr = 1;
#endif
#if defined(SO_REUSEPORT)
if (use_reuseaddr) {
int on = flag;
setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (const void*) &on, (socklen_t) sizeof(on));
}
#endif
#if defined(SO_REUSEADDR)
if (use_reuseaddr) {
int on = flag;
int ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void*) &on, (socklen_t) sizeof(on));
if (ret < 0)
perror("SO_REUSEADDR");
}
#endif
return 0;
}
}
int sock_bind_to_device(evutil_socket_t fd, const unsigned char* ifname) {
if (fd >= 0 && ifname && ifname[0]) {
#if defined(SO_BINDTODEVICE)
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, (const char*) ifname, sizeof(ifr.ifr_name));
if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, (void *) &ifr, sizeof(ifr)) < 0) {
if (errno == EPERM)
perror("You must obtain superuser privileges to bind a socket to device");
else
perror("Cannot bind socket to device");
return -1;
}
return 0;
#endif
}
return 0;
}
int addr_connect(evutil_socket_t fd, const ioa_addr* addr, int *out_errno)
{
if (!addr || fd < 0)
return -1;
else {
int err = 0;
do {
if (addr->ss.sa_family == AF_INET) {
err = connect(fd, (const struct sockaddr *) addr, sizeof(struct sockaddr_in));
} else if (addr->ss.sa_family == AF_INET6) {
err = connect(fd, (const struct sockaddr *) addr, sizeof(struct sockaddr_in6));
} else {
return -1;
}
} while (err < 0 && errno == EINTR);
if(out_errno)
*out_errno = errno;
if (err < 0 && errno != EINPROGRESS)
perror("Connect");
return err;
}
}
int addr_bind(evutil_socket_t fd, const ioa_addr* addr, int reusable)
{
if (!addr || fd < 0) {
return -1;
} else {
int ret = -1;
socket_set_reusable(fd, reusable);
if (addr->ss.sa_family == AF_INET) {
do {
ret = bind(fd, (const struct sockaddr *) addr, sizeof(struct sockaddr_in));
} while (ret < 0 && errno == EINTR);
} else if (addr->ss.sa_family == AF_INET6) {
const int off = 0;
setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (const char *) &off, sizeof(off));
do {
ret = bind(fd, (const struct sockaddr *) addr, sizeof(struct sockaddr_in6));
} while (ret < 0 && errno == EINTR);
} else {
return -1;
}
if(ret<0) {
int err = errno;
perror("bind");
char str[129];
addr_to_string(addr,(u08bits*)str);
TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "Trying to bind fd %d to <%s>: errno=%d\n", fd, str, err);
}
return ret;
}
}
int addr_get_from_sock(evutil_socket_t fd, ioa_addr *addr)
{
if (fd < 0 || !addr)
return -1;
else {
ioa_addr a;
a.ss.sa_family = AF_INET6;
socklen_t socklen = get_ioa_addr_len(&a);
if (getsockname(fd, (struct sockaddr*) &a, &socklen) < 0) {
a.ss.sa_family = AF_INET;
socklen = get_ioa_addr_len(&a);
if (getsockname(fd, (struct sockaddr*) &a, &socklen) < 0) {
return -1;
}
}
addr_cpy(addr, &a);
return 0;
}
}
/////////////////// MTU /////////////////////////////////////////
int set_socket_df(evutil_socket_t fd, int family, int value)
{
int ret=0;
#if defined(IP_DONTFRAG) && defined(IPPROTO_IP) //BSD
{
const int val=value;
/* kernel sets DF bit on outgoing IP packets */
if(family==AF_INET) {
ret = setsockopt(fd, IPPROTO_IP, IP_DONTFRAG, &val, sizeof(val));
} else {
#if defined(IPV6_DONTFRAG) && defined(IPPROTO_IPV6)
ret = setsockopt(fd, IPPROTO_IPV6, IPV6_DONTFRAG, &val, sizeof(val));
#else
#error CANNOT SET IPV6 SOCKET DF FLAG (1)
#endif
}
if(ret<0) {
int err=errno;
perror("set socket df:");
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s: set sockopt failed: fd=%d, err=%d, family=%d\n",__FUNCTION__,fd,err,family);
}
}
#elif defined(IPPROTO_IP) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO) && defined(IP_PMTUDISC_DONT) //LINUX
{
/* kernel sets DF bit on outgoing IP packets */
if(family==AF_INET) {
int val=IP_PMTUDISC_DO;
if(!value) val=IP_PMTUDISC_DONT;
ret = setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val));
} else {
#if defined(IPPROTO_IPV6) && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO) && defined(IPV6_PMTUDISC_DONT)
int val=IPV6_PMTUDISC_DO;
if(!value) val=IPV6_PMTUDISC_DONT;
ret = setsockopt(fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &val, sizeof(val));
#else
#error CANNOT SET IPV6 SOCKET DF FLAG (2)
#endif
}
if(ret<0) {
perror("set DF");
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s: set sockopt failed\n",__FUNCTION__);
}
}
#else
//CANNOT SET SOCKET DF FLAG (3) : UNKNOWN PLATFORM
UNUSED_ARG(fd);
UNUSED_ARG(family);
UNUSED_ARG(value);
#endif
return ret;
}
static int get_mtu_from_ssl(SSL* ssl)
{
int ret = SOSO_MTU;
#if !defined(TURN_NO_DTLS)
if(ssl)
ret = BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
#else
UNUSED_ARG(ssl);
#endif
return ret;
}
static void set_query_mtu(SSL* ssl) {
if(ssl) {
#if defined(SSL_OP_NO_QUERY_MTU)
SSL_set_options(ssl, SSL_OP_NO_QUERY_MTU);
#else
;
#endif
}
}
int decrease_mtu(SSL* ssl, int mtu, int verbose)
{
if (!ssl)
return mtu;
int new_mtu = get_mtu_from_ssl(ssl);
if (new_mtu < 1)
new_mtu = mtu;
if (new_mtu > MAX_MTU)
mtu = MAX_MTU;
if (new_mtu > 0 && new_mtu < MIN_MTU)
mtu = MIN_MTU;
else if (new_mtu < mtu)
mtu = new_mtu;
else
mtu -= MTU_STEP;
if (mtu < MIN_MTU)
mtu = MIN_MTU;
set_query_mtu(ssl);
if (verbose)
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "1. mtu to use: %d\n", mtu);
#if !defined(TURN_NO_DTLS)
SSL_set_mtu(ssl,mtu);
BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_SET_MTU, mtu, NULL);
#endif
return mtu;
}
int set_mtu_df(SSL* ssl, evutil_socket_t fd, int family, int mtu, int df_value, int verbose) {
if(!ssl || fd<0) return 0;
int ret=set_socket_df(fd, family, df_value);
if(!mtu) mtu=SOSO_MTU;
else if(mtu<MIN_MTU) mtu=MIN_MTU;
else if(mtu>MAX_MTU) mtu=MAX_MTU;
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)
SSL_set_mtu(ssl,mtu);
BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_SET_MTU, mtu, NULL);
#endif
if(verbose) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"4. new mtu: %d\n",get_mtu_from_ssl(ssl));
return ret;
}
int get_socket_mtu(evutil_socket_t fd, int family, int verbose)
{
int ret = 0;
UNUSED_ARG(fd);
UNUSED_ARG(family);
UNUSED_ARG(verbose);
#if defined(IP_MTU)
int val = 0;
socklen_t slen=sizeof(val);
if(family==AF_INET) {
ret = getsockopt(fd, IPPROTO_IP, IP_MTU, &val, &slen);
} else {
#if defined(IPPROTO_IPV6) && defined(IPV6_MTU)
ret = getsockopt(fd, IPPROTO_IPV6, IPV6_MTU, &val, &slen);
#endif
;
}
ret = val;
#endif
if (verbose)
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: final=%d\n", __FUNCTION__, ret);
return ret;
}
//////////////////// socket error handle ////////////////////
int handle_socket_error() {
switch (errno) {
case EINTR:
/* Interrupted system call.
* Just ignore.
*/
return 1;
case ENOBUFS:
/* No buffers, temporary condition.
* Just ignore and try later.
*/
return 1;
case EAGAIN:
#if defined(EWOULDBLOCK)
#if (EWOULDBLOCK != EAGAIN)
case EWOULDBLOCK:
#endif
#endif
return 1;
case EMSGSIZE:
return 1;
case EBADF:
/* Invalid socket.
* Must close connection.
*/
return 0;
case EHOSTDOWN:
/* Host is down.
* Just ignore, might be an attacker
* sending fake ICMP messages.
*/
return 1;
case ECONNRESET:
case ECONNREFUSED:
/* Connection reset by peer. */
return 0;
case ENOMEM:
/* Out of memory.
* Must close connection.
*/
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Out of memory!\n");
return 0;
case EACCES:
/* Permission denied.
* Just ignore, we might be blocked
* by some firewall policy. Try again
* and hope for the best.
*/
return 1;
default:
/* Something unexpected happened */
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Unexpected error! (errno = %d)\n", errno);
return 0;
}
}
//////////////////// Misc utils //////////////////////////////
char *skip_blanks(char* s)
{
while(*s==' ' || *s=='\t' || *s=='\n')
++s;
return s;
}
//////////////////// Config file search //////////////////////
#define Q(x) #x
#define QUOTE(x) Q(x)
#define ETCDIR INSTALL_PREFIX/etc/
#define QETCDIR QUOTE(ETCDIR)
#define ETCDIR1 INSTALL_PREFIX/etc/turnserver/
#define QETCDIR1 QUOTE(ETCDIR1)
#define ETCDIR2 INSTALL_PREFIX/etc/coturn/
#define QETCDIR2 QUOTE(ETCDIR2)
static const char *config_file_search_dirs[] = {"./", "./turnserver/", "./coturn/", "./etc/", "./etc/turnserver/", "./etc/coturn/", "../etc/", "../etc/turnserver/", "../etc/coturn/", "/etc/", "/etc/turnserver/", "/etc/coturn/", "/usr/local/etc/", "/usr/local/etc/turnserver/", "/usr/local/etc/coturn/", QETCDIR, QETCDIR1, QETCDIR2, NULL };
static char *c_execdir=NULL;
void set_execdir(void)
{
/* On some systems, this may give us the execution path */
char *_var = getenv("_");
if(_var && *_var) {
_var = strdup(_var);
char *edir=_var;
if(edir[0]!='.')
edir = strstr(edir,"/");
if(edir && *edir)
edir = dirname(edir);
else
edir = dirname(_var);
if(c_execdir)
turn_free(c_execdir,strlen(c_execdir)+1);
c_execdir = strdup(edir);
turn_free(_var,strlen(_var)+1);
}
}
void print_abs_file_name(const char *msg1, const char *msg2, const char *fn)
{
char absfn[1025];
absfn[0]=0;
if(fn) {
while(fn[0] && fn[0]==' ') ++fn;
if(fn[0]) {
if(fn[0]=='/') {
STRCPY(absfn,fn);
} else {
if(fn[0]=='.' && fn[1]=='/')
fn+=2;
if(!getcwd(absfn,sizeof(absfn)-1))
absfn[0]=0;
size_t blen=strlen(absfn);
if(blen<sizeof(absfn)-1) {
strncpy(absfn+blen,"/",sizeof(absfn)-blen);
strncpy(absfn+blen+1,fn,sizeof(absfn)-blen-1);
} else {
STRCPY(absfn,fn);
}
absfn[sizeof(absfn)-1]=0;
}
}
}
if(absfn[0]) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s%s file found: %s\n", msg1, msg2, absfn);
}
}
char* find_config_file(const char *config_file, int print_file_name)
{
char *full_path_to_config_file = NULL;
if (config_file && config_file[0]) {
if ((config_file[0] == '/')||(config_file[0] == '~')) {
FILE *f = fopen(config_file, "r");
if (f) {
fclose(f);
full_path_to_config_file = strdup(config_file);
}
} else {
int i = 0;
size_t cflen = strlen(config_file);
while (config_file_search_dirs[i]) {
size_t dirlen = strlen(config_file_search_dirs[i]);
size_t fnsz = sizeof(char) * (dirlen + cflen + 10);
char *fn = (char*)turn_malloc(fnsz+1);
strncpy(fn, config_file_search_dirs[i], fnsz);
strncpy(fn + dirlen, config_file, fnsz-dirlen);
fn[fnsz]=0;
FILE *f = fopen(fn, "r");
if (f) {
fclose(f);
if (print_file_name)
print_abs_file_name("","Config",fn);
full_path_to_config_file = fn;
break;
}
turn_free(fn,fnsz+1);
if(config_file_search_dirs[i][0]!='/' &&
config_file_search_dirs[i][0]!='.' &&
c_execdir && c_execdir[0]) {
size_t celen = strlen(c_execdir);
fnsz = sizeof(char) * (dirlen + cflen + celen + 10);
fn = (char*)turn_malloc(fnsz+1);
strncpy(fn,c_execdir,fnsz);
size_t fnlen=strlen(fn);
if(fnlen<fnsz) {
strncpy(fn+fnlen,"/",fnsz-fnlen);
fnlen=strlen(fn);
if(fnlen<fnsz) {
strncpy(fn+fnlen, config_file_search_dirs[i], fnsz-fnlen);
fnlen=strlen(fn);
if(fnlen<fnsz) {
strncpy(fn+fnlen, config_file, fnsz-fnlen);
}
}
}
fn[fnsz]=0;
if(strstr(fn,"//")!=fn) {
f = fopen(fn, "r");
if (f) {
fclose(f);
if (print_file_name)
print_abs_file_name("","Config",fn);
full_path_to_config_file = fn;
break;
}
}
turn_free(fn,fnsz+1);
}
++i;
}
}
if(!full_path_to_config_file) {
if(strstr(config_file,"etc/")==config_file) {
return find_config_file(config_file+4, print_file_name);
}
}
}
return full_path_to_config_file;
}
/////////////////// SYS SETTINGS ///////////////////////
void ignore_sigpipe(void)
{
/* Ignore SIGPIPE from TCP sockets */
if(signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
perror("Cannot set SIGPIPE handler");
}
}
static u64bits turn_getRandTime(void) {
struct timespec tp={0,0};
#if defined(CLOCK_REALTIME)
clock_gettime(CLOCK_REALTIME, &tp);
#else
tp.tv_sec = time(NULL);
#endif
u64bits current_time = (u64bits)(tp.tv_sec);
u64bits current_mstime = (u64bits)(current_time + (tp.tv_nsec));
return current_mstime;
}
unsigned long set_system_parameters(int max_resources)
{
srandom((unsigned int) (turn_getRandTime() + (unsigned int)((long)(&turn_getRandTime))));
setlocale(LC_ALL, "C");
build_base64_decoding_table();
ignore_sigpipe();
if(max_resources) {
struct rlimit rlim;
if(getrlimit(RLIMIT_NOFILE, &rlim)<0) {
perror("Cannot get system limit");
} else {
rlim.rlim_cur = rlim.rlim_max;
while((setrlimit(RLIMIT_NOFILE, &rlim)<0) && (rlim.rlim_cur>0)) {
rlim.rlim_cur = rlim.rlim_cur>>1;
}
return (unsigned long)rlim.rlim_cur;
}
}
return 0;
}
////////////////////// Base 64 ////////////////////////////
static char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'};
static char *decoding_table = NULL;
static size_t mod_table[] = {0, 2, 1};
char *base64_encode(const unsigned char *data,
size_t input_length,
size_t *output_length) {
*output_length = 4 * ((input_length + 2) / 3);
char *encoded_data = (char*)turn_malloc(*output_length+1);
if (encoded_data == NULL) return NULL;
size_t i,j;
for (i = 0, j = 0; i < input_length;) {
u32bits octet_a = i < input_length ? data[i++] : 0;
u32bits octet_b = i < input_length ? data[i++] : 0;
u32bits octet_c = i < input_length ? data[i++] : 0;
u32bits triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
encoded_data[j++] = encoding_table[(triple >> 3 * 6) & 0x3F];
encoded_data[j++] = encoding_table[(triple >> 2 * 6) & 0x3F];
encoded_data[j++] = encoding_table[(triple >> 1 * 6) & 0x3F];
encoded_data[j++] = encoding_table[(triple >> 0 * 6) & 0x3F];
}
for (i = 0; i < mod_table[input_length % 3]; i++)
encoded_data[*output_length - 1 - i] = '=';
encoded_data[*output_length]=0;
return encoded_data;
}
void build_base64_decoding_table() {
decoding_table = (char*)turn_malloc(256);
ns_bzero(decoding_table,256);
int i;
for (i = 0; i < 64; i++)
decoding_table[(unsigned char) encoding_table[i]] = (char)i;
}
unsigned char *base64_decode(const char *data,
size_t input_length,
size_t *output_length) {
if (decoding_table == NULL) build_base64_decoding_table();
if (input_length % 4 != 0) return NULL;
*output_length = input_length / 4 * 3;
if (data[input_length - 1] == '=') (*output_length)--;
if (data[input_length - 2] == '=') (*output_length)--;
unsigned char *decoded_data = (unsigned char*)turn_malloc(*output_length);
if (decoded_data == NULL) return NULL;
int i;
size_t j;
for (i = 0, j = 0; i < (int)input_length;) {
uint32_t sextet_a =
data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]];
uint32_t sextet_b =
data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]];
uint32_t sextet_c =
data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]];
uint32_t sextet_d =
data[i] == '=' ? 0 & i++ : decoding_table[(int)data[i++]];
uint32_t triple = (sextet_a << 3 * 6) + (sextet_b << 2 * 6)
+ (sextet_c << 1 * 6) + (sextet_d << 0 * 6);
if (j < *output_length)
decoded_data[j++] = (triple >> 2 * 8) & 0xFF;
if (j < *output_length)
decoded_data[j++] = (triple >> 1 * 8) & 0xFF;
if (j < *output_length)
decoded_data[j++] = (triple >> 0 * 8) & 0xFF;
}
return decoded_data;
}
////////////////// SSL /////////////////////
static const char* turn_get_method(const SSL_METHOD *method, const char* mdefault)
{
{
if(!method)
return mdefault;
else {
#ifndef OPENSSL_NO_SSL2
if(method == SSLv2_server_method()) {
return "SSLv2";
} else if(method == SSLv2_client_method()) {
return "SSLv2";
} else
#endif
if(method == SSLv3_server_method()) {
return "SSLv3";
} else if(method == SSLv3_client_method()) {
return "SSLv3";
} else if(method == SSLv23_server_method()) {
return "SSLv23";
} else if(method == SSLv23_client_method()) {
return "SSLv23";
} else if(method == TLSv1_server_method()) {
return "TLSv1.0";
} else if(method == TLSv1_client_method()) {
return "TLSv1.0";
#if defined(SSL_TXT_TLSV1_1)
} 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)
} 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)
} else if(method == DTLSv1_server_method()) {
return "DTLSv1.0";
} else if(method == DTLSv1_client_method()) {
return "DTLSv1.0";
#endif
} else {
if(mdefault)
return mdefault;
return "UNKNOWN";
}
}
}
}
const char* turn_get_ssl_method(SSL *ssl, const char* mdefault)
{
if(!ssl)
return mdefault;
else {
const SSL_METHOD *method = SSL_get_ssl_method(ssl);
if(!method)
return mdefault;
else
return turn_get_method(method, mdefault);
}
}
//////////// EVENT BASE ///////////////
struct event_base *turn_event_base_new(void)
{
struct event_config *cfg = event_config_new();
event_config_set_flag(cfg,EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST);
return event_base_new_with_config(cfg);
}
//////////////////////////////////////////////////////////////

163
src/apps/common/apputils.h Normal file
View File

@ -0,0 +1,163 @@
/*
* Copyright (C) 2011, 2012, 2013 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 __APP_LIB__
#define __APP_LIB__
#include <event2/event.h>
#include <openssl/ssl.h>
#include "ns_turn_ioaddr.h"
#ifdef __cplusplus
extern "C" {
#endif
//////////// Common defines ///////////////////////////
#define PEER_DEFAULT_PORT (3480)
#define DTLS_MAX_RECV_TIMEOUT (5)
#define UR_CLIENT_SOCK_BUF_SIZE (65536)
#define UR_SERVER_SOCK_BUF_SIZE (UR_CLIENT_SOCK_BUF_SIZE * 32)
extern int IS_TURN_SERVER;
/////////// SSL //////////////////////////
enum _TURN_TLS_TYPE {
TURN_TLS_NO=0,
TURN_TLS_SSL23,
TURN_TLS_v1_0,
#if defined(SSL_TXT_TLSV1_1)
TURN_TLS_v1_1,
#if defined(SSL_TXT_TLSV1_2)
TURN_TLS_v1_2,
#endif
#endif
TURN_TLS_TOTAL
};
typedef enum _TURN_TLS_TYPE TURN_TLS_TYPE;
//////////////////////////////////////////
#define EVENT_DEL(ev) if(ev) { event_del(ev); event_free(ev); ev=NULL; }
//////////////////////////////////////////
#define ioa_socket_raw int
///////////////////////// Sockets ///////////////////////////////
#if defined(WIN32)
/** Do the platform-specific call needed to close a socket returned from
socket() or accept(). */
#define socket_closesocket(s) closesocket(s)
#else
/** Do the platform-specific call needed to close a socket returned from
socket() or accept(). */
#define socket_closesocket(s) close(s)
#endif
void read_spare_buffer(evutil_socket_t fd);
int set_sock_buf_size(evutil_socket_t fd, int sz);
int socket_set_reusable(evutil_socket_t fd, int reusable);
int sock_bind_to_device(evutil_socket_t fd, const unsigned char* ifname);
int socket_set_nonblocking(evutil_socket_t fd);
int socket_tcp_set_keepalive(evutil_socket_t fd);
int addr_connect(evutil_socket_t fd, const ioa_addr* addr, int *out_errno);
int addr_bind(evutil_socket_t fd, const ioa_addr* addr, int reusable);
int addr_get_from_sock(evutil_socket_t fd, ioa_addr *addr);
int handle_socket_error(void);
/////////////////////// SYS /////////////////////
void ignore_sigpipe(void);
unsigned long set_system_parameters(int max_resources);
///////////////////////// MTU //////////////////////////
#define MAX_MTU (1500 - 20 - 8)
#define MIN_MTU (576 - 20 - 8)
#define SOSO_MTU (1300)
#define MTU_STEP (68)
int set_socket_df(evutil_socket_t fd, int family, int value);
int set_mtu_df(SSL* ssl, evutil_socket_t fd, int family, int mtu, int df_value, int verbose);
int decrease_mtu(SSL* ssl, int mtu, int verbose);
int get_socket_mtu(evutil_socket_t fd, int family, int verbose);
////////////////// Misc utils /////////////////////////
char *skip_blanks(char* s);
////////////////// File search ////////////////////////
char* find_config_file(const char *config_file, int print_file_name);
void set_execdir(void);
void print_abs_file_name(const char *msg1, const char *msg2, const char *fn);
////////////////// Base64 /////////////////////////////
char *base64_encode(const unsigned char *data,
size_t input_length,
size_t *output_length);
void build_base64_decoding_table(void);
unsigned char *base64_decode(const char *data,
size_t input_length,
size_t *output_length);
///////////// SSL ////////////////
const char* turn_get_ssl_method(SSL *ssl, const char* mdefault);
//////////// Event Base /////////////////////
struct event_base *turn_event_base_new(void);
///////////////////////////////////////////////////////
#ifdef __cplusplus
}
#endif
#endif //__APP_LIB__

View File

@ -0,0 +1,383 @@
/*
* Copyright (C) 2011, 2012, 2013 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 <stdlib.h>
#include <stdarg.h>
#if !defined(TURN_NO_HIREDIS)
#include "hiredis_libevent2.h"
#include "ns_turn_utils.h"
#include <event2/bufferevent.h>
#include <event2/buffer.h>
#include <hiredis/hiredis.h>
#include <hiredis/async.h>
//////////////// Libevent context ///////////////////////
struct redisLibeventEvents
{
redisAsyncContext *context;
int invalid;
int allocated;
struct event_base *base;
struct event *rev, *wev;
int rev_set, wev_set;
char *ip;
int port;
char *pwd;
int db;
};
///////////// Messages ////////////////////////////
struct redis_message
{
char format[513];
char arg[513];
};
/////////////////// forward declarations ///////////////
static void redis_reconnect(struct redisLibeventEvents *e);
//////////////////////////////////////////////////////////
static int redis_le_valid(struct redisLibeventEvents *e)
{
return (e && !(e->invalid) && (e->context));
}
/////////////////// Callbacks ////////////////////////////
static void redisLibeventReadEvent(int fd, short event, void *arg) {
((void)fd); ((void)event);
struct redisLibeventEvents *e = (struct redisLibeventEvents*)arg;
if(redis_le_valid(e)) {
{
char buf[8];
int len = 0;
do {
len = recv(fd,buf,sizeof(buf),MSG_PEEK);
} while((len<0)&&(errno == EINTR));
if(len<1) {
e->invalid = 1;
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Redis connection broken: e=0x%lx\n", __FUNCTION__, (unsigned long)e);
}
}
if(redis_le_valid(e)) {
redisAsyncHandleRead(e->context);
}
}
}
static void redisLibeventWriteEvent(int fd, short event, void *arg) {
((void)fd); ((void)event);
struct redisLibeventEvents *e = (struct redisLibeventEvents*)arg;
if(redis_le_valid(e)) {
redisAsyncHandleWrite(e->context);
}
}
static void redisLibeventAddRead(void *privdata) {
struct redisLibeventEvents *e = (struct redisLibeventEvents*)privdata;
if(e && (e->rev) && !(e->rev_set)) {
event_add(e->rev,NULL);
e->rev_set = 1;
}
}
static void redisLibeventDelRead(void *privdata) {
struct redisLibeventEvents *e = (struct redisLibeventEvents*)privdata;
if(e && e->rev && e->rev_set) {
event_del(e->rev);
e->rev_set = 0;
}
}
static void redisLibeventAddWrite(void *privdata) {
struct redisLibeventEvents *e = (struct redisLibeventEvents*)privdata;
if(e && (e->wev) && !(e->wev_set)) {
event_add(e->wev,NULL);
e->wev_set = 1;
}
}
static void redisLibeventDelWrite(void *privdata) {
struct redisLibeventEvents *e = (struct redisLibeventEvents*)privdata;
if(e && e->wev && e->wev_set) {
event_del(e->wev);
e->wev_set = 0;
}
}
static void redisLibeventCleanup(void *privdata)
{
if (privdata) {
struct redisLibeventEvents *e = (struct redisLibeventEvents *) privdata;
if (e->allocated) {
if (e->rev) {
if(e->rev_set)
event_del(e->rev);
event_free(e->rev);
e->rev = NULL;
}
e->rev_set = 0;
if (e->wev) {
if(e->wev_set)
event_del(e->wev);
event_free(e->wev);
e->wev = NULL;
}
e->wev_set = 0;
e->context = NULL;
}
}
}
///////////////////////// Send-receive ///////////////////////////
void redis_async_init(void)
{
;
}
int is_redis_asyncconn_good(redis_context_handle rch)
{
if(rch) {
struct redisLibeventEvents *e = (struct redisLibeventEvents*)rch;
if(redis_le_valid(e))
return 1;
}
return 0;
}
void send_message_to_redis(redis_context_handle rch, const char *command, const char *key, const char *format,...)
{
if(!rch) {
return;
} else {
struct redisLibeventEvents *e = (struct redisLibeventEvents*)rch;
if(!redis_le_valid(e)) {
redis_reconnect(e);
}
if(!redis_le_valid(e)) {
;
} else {
redisAsyncContext *ac=e->context;
struct redis_message rm;
snprintf(rm.format,sizeof(rm.format)-3,"%s %s ", command, key);
strcpy(rm.format+strlen(rm.format),"%s");
va_list args;
va_start (args, format);
vsnprintf(rm.arg, sizeof(rm.arg)-1, format, args);
va_end (args);
if((redisAsyncCommand(ac, NULL, e, rm.format, rm.arg)!=REDIS_OK)) {
e->invalid = 1;
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Redis connection broken: ac=0x%lx, e=0x%x\n", __FUNCTION__,(unsigned long)ac,(unsigned long)e);
}
}
}
}
///////////////////////// Attach /////////////////////////////////
redis_context_handle redisLibeventAttach(struct event_base *base, char *ip0, int port0, char *pwd, int db)
{
struct redisLibeventEvents *e = NULL;
redisAsyncContext *ac = NULL;
char ip[256];
if(ip0 && ip0[0])
STRCPY(ip,ip0);
else
STRCPY(ip,"127.0.0.1");
int port = DEFAULT_REDIS_PORT;
if(port0>0)
port=port0;
ac = redisAsyncConnect(ip, port);
if (!ac) {
fprintf(stderr,"Error: %s:%s\n", ac->errstr, ac->c.errstr);
return NULL;
}
/* Create container for context and r/w events */
e = (struct redisLibeventEvents*)turn_malloc(sizeof(struct redisLibeventEvents));
ns_bzero(e,sizeof(struct redisLibeventEvents));
e->allocated = 1;
e->context = ac;
e->base = base;
e->ip = strdup(ip);
e->port = port;
if(pwd)
e->pwd = strdup(pwd);
e->db = db;
/* Register functions to start/stop listening for events */
ac->ev.addRead = redisLibeventAddRead;
ac->ev.delRead = redisLibeventDelRead;
ac->ev.addWrite = redisLibeventAddWrite;
ac->ev.delWrite = redisLibeventDelWrite;
ac->ev.cleanup = redisLibeventCleanup;
ac->ev.data = e;
/* Initialize and install read/write events */
e->rev = event_new(e->base,e->context->c.fd,
EV_READ,redisLibeventReadEvent,
e);
e->wev = event_new(e->base,e->context->c.fd,
EV_WRITE,redisLibeventWriteEvent,
e);
if (e->rev == NULL || e->wev == NULL) {
turn_free(e, sizeof(struct redisLibeventEvents));
return NULL;
}
event_add(e->wev, NULL);
e->wev_set = 1;
//Authentication
if(redis_le_valid(e) && pwd) {
if(redisAsyncCommand(ac, NULL, e, "AUTH %s", pwd)!=REDIS_OK) {
e->invalid = 1;
}
}
if(redis_le_valid(e)) {
if(redisAsyncCommand(ac, NULL, e, "SELECT %d", db)!=REDIS_OK) {
e->invalid = 1;
}
}
return (redis_context_handle)e;
}
static void redis_reconnect(struct redisLibeventEvents *e)
{
if(!e || !(e->allocated))
return;
if (e->rev) {
if(e->rev_set)
event_del(e->rev);
event_free(e->rev);
e->rev = NULL;
}
e->rev_set = 0;
if (e->wev) {
if(e->wev_set)
event_del(e->wev);
event_free(e->wev);
e->wev = NULL;
}
e->wev_set = 0;
redisAsyncContext *ac = NULL;
if(e->context) {
e->context = NULL;
}
ac = redisAsyncConnect(e->ip, e->port);
if(!ac) {
return;
}
e->context = ac;
/* Register functions to start/stop listening for events */
ac->ev.addRead = redisLibeventAddRead;
ac->ev.delRead = redisLibeventDelRead;
ac->ev.addWrite = redisLibeventAddWrite;
ac->ev.delWrite = redisLibeventDelWrite;
ac->ev.cleanup = redisLibeventCleanup;
ac->ev.data = e;
/* Initialize and install read/write events */
e->rev = event_new(e->base,e->context->c.fd,
EV_READ,redisLibeventReadEvent,
e);
e->wev = event_new(e->base,e->context->c.fd,
EV_WRITE,redisLibeventWriteEvent,
e);
if (e->rev == NULL || e->wev == NULL) {
return;
}
event_add(e->wev, NULL);
e->wev_set = 1;
e->invalid = 0;
//Authentication
if(redis_le_valid(e) && e->pwd) {
if(redisAsyncCommand(ac, NULL, e, "AUTH %s", e->pwd)!=REDIS_OK) {
e->invalid = 1;
}
}
if(redis_le_valid(e)) {
if(redisAsyncCommand(ac, NULL, e, "SELECT %d", e->db)!=REDIS_OK) {
e->invalid = 1;
}
}
if(redis_le_valid(e)) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Re-connected to redis, async\n", __FUNCTION__);
}
}
/////////////////////////////////////////////////////////
#endif
/* TURN_NO_HIREDIS */

View File

@ -0,0 +1,67 @@
/*
* Copyright (C) 2011, 2012, 2013 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 __HIREDIS_LIBEVENT_H__
#define __HIREDIS_LIBEVENT_H__
#if !defined(TURN_NO_HIREDIS)
#include <event2/event.h>
#ifdef __cplusplus
extern "C" {
#endif
//////////////////////////////////////
#define DEFAULT_REDIS_PORT (6379)
typedef void* redis_context_handle;
//////////////////////////////////////
void redis_async_init(void);
redis_context_handle redisLibeventAttach(struct event_base *base, char *ip, int port, char *pwd, int db);
void send_message_to_redis(redis_context_handle rch, const char *command, const char *key, const char *format,...);
int is_redis_asyncconn_good(redis_context_handle rch);
#ifdef __cplusplus
}
#endif
#endif
/* TURN_NO_HIREDIS */
#endif
/*__HIREDIS_LIBEVENT_H__*/

View File

@ -0,0 +1,643 @@
/*
* Copyright (C) 2011, 2012, 2013 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 "ns_turn_utils.h"
#include "ns_turn_ioalib.h"
#include "ns_turn_msg_defs.h"
#include <time.h>
#include <pthread.h>
#include <syslog.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
////////// LOG TIME OPTIMIZATION ///////////
static volatile turn_time_t log_start_time = 0;
volatile int _log_time_value_set = 0;
volatile turn_time_t _log_time_value = 0;
static inline turn_time_t log_time(void)
{
if(!log_start_time)
log_start_time = turn_time();
if(_log_time_value_set)
return (_log_time_value - log_start_time);
return (turn_time() - log_start_time);
}
////////// MUTEXES /////////////
#define MAGIC_CODE (0xEFCD1983)
int turn_mutex_lock(const turn_mutex *mutex) {
if(mutex && mutex->mutex && (mutex->data == MAGIC_CODE)) {
int ret = 0;
ret = pthread_mutex_lock((pthread_mutex_t*)mutex->mutex);
if(ret<0) {
perror("Mutex lock");
}
return ret;
} else {
printf("Uninitialized mutex\n");
return -1;
}
}
int turn_mutex_unlock(const turn_mutex *mutex) {
if(mutex && mutex->mutex && (mutex->data == MAGIC_CODE)) {
int ret = 0;
ret = pthread_mutex_unlock((pthread_mutex_t*)mutex->mutex);
if(ret<0) {
perror("Mutex unlock");
}
return ret;
} else {
printf("Uninitialized mutex\n");
return -1;
}
}
int turn_mutex_init(turn_mutex* mutex) {
if(mutex) {
mutex->data=MAGIC_CODE;
mutex->mutex=turn_malloc(sizeof(pthread_mutex_t));
pthread_mutex_init((pthread_mutex_t*)mutex->mutex,NULL);
return 0;
} else {
return -1;
}
}
int turn_mutex_init_recursive(turn_mutex* mutex) {
int ret = -1;
if (mutex) {
pthread_mutexattr_t attr;
if (pthread_mutexattr_init(&attr) < 0) {
perror("Cannot init mutex attr");
} else {
if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) < 0) {
perror("Cannot set type on mutex attr");
} else {
mutex->mutex = turn_malloc(sizeof(pthread_mutex_t));
mutex->data = MAGIC_CODE;
if ((ret = pthread_mutex_init((pthread_mutex_t*) mutex->mutex,
&attr)) < 0) {
perror("Cannot init mutex");
mutex->data = 0;
turn_free(mutex->mutex,sizeof(pthread_mutex_t));
mutex->mutex = NULL;
}
}
pthread_mutexattr_destroy(&attr);
}
}
return ret;
}
int turn_mutex_destroy(turn_mutex* mutex) {
if(mutex && mutex->mutex && mutex->data == MAGIC_CODE) {
int ret = 0;
ret = pthread_mutex_destroy((pthread_mutex_t*)(mutex->mutex));
turn_free(mutex->mutex, sizeof(pthread_mutex_t));
mutex->mutex=NULL;
mutex->data=0;
return ret;
} else {
return 0;
}
}
///////////////////////// LOG ///////////////////////////////////
#if defined(TURN_LOG_FUNC_IMPL)
extern void TURN_LOG_FUNC_IMPL(TURN_LOG_LEVEL level, const s08bits* format, va_list args);
#endif
static int no_stdout_log = 0;
void set_no_stdout_log(int val)
{
no_stdout_log = val;
}
void turn_log_func_default(TURN_LOG_LEVEL level, const s08bits* 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
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);
}
#endif
va_end(args);
}
}
void addr_debug_print(int verbose, const ioa_addr *addr, const s08bits* s)
{
if (verbose) {
if (!addr) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: EMPTY\n", s);
} else {
s08bits addrbuf[INET6_ADDRSTRLEN];
if (!s)
s = "";
if (addr->ss.sa_family == AF_INET) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "IPv4. %s: %s:%d\n", s, inet_ntop(AF_INET,
&addr->s4.sin_addr, addrbuf, INET6_ADDRSTRLEN),
nswap16(addr->s4.sin_port));
} else if (addr->ss.sa_family == AF_INET6) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "IPv6. %s: %s:%d\n", s, inet_ntop(AF_INET6,
&addr->s6.sin6_addr, addrbuf, INET6_ADDRSTRLEN),
nswap16(addr->s6.sin6_port));
} else {
if (addr_any_no_port(addr)) {
TURN_LOG_FUNC(
TURN_LOG_LEVEL_INFO,
"IP. %s: 0.0.0.0:%d\n",
s,
nswap16(addr->s4.sin_port));
} else {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: wrong IP address family: %d\n", s,
(int) (addr->ss.sa_family));
}
}
}
}
}
/*************************************/
#define FILE_STR_LEN (1025)
static FILE* _rtpfile = NULL;
static int to_syslog = 0;
static int simple_log = 0;
static char log_fn[FILE_STR_LEN]="\0";
static char log_fn_base[FILE_STR_LEN]="\0";
static turn_mutex log_mutex;
static int log_mutex_inited = 0;
static void log_lock(void) {
if(!log_mutex_inited) {
log_mutex_inited=1;
turn_mutex_init_recursive(&log_mutex);
}
turn_mutex_lock(&log_mutex);
}
static void log_unlock(void) {
turn_mutex_unlock(&log_mutex);
}
static void get_date(char *s, size_t sz) {
time_t curtm;
struct tm* tm_info;
curtm = time(NULL);
tm_info = localtime(&curtm);
strftime(s, sz, "%F", tm_info);
}
void set_logfile(const char *fn)
{
if(fn) {
log_lock();
if(strcmp(fn,log_fn_base)) {
reset_rtpprintf();
STRCPY(log_fn_base,fn);
}
log_unlock();
}
}
void reset_rtpprintf(void)
{
log_lock();
if(_rtpfile) {
if(_rtpfile != stdout)
fclose(_rtpfile);
_rtpfile = NULL;
}
log_unlock();
}
static void set_log_file_name(char *base, char *f)
{
if(simple_log) {
STRCPY(f,base);
return;
}
char logdate[125];
char *tail=strdup(".log");
get_date(logdate,sizeof(logdate));
char *base1=strdup(base);
int len=(int)strlen(base1);
--len;
while(len>=0) {
if((base1[len]==' ')||(base1[len]=='\t')) {
base1[len]='_';
}
--len;
}
len=(int)strlen(base1);
while(len>=0) {
if(base1[len]=='/')
break;
else if(base1[len]=='.') {
turn_free(tail,strlen(tail)+1);
tail=strdup(base1+len);
base1[len]=0;
if(strlen(tail)<2) {
turn_free(tail,strlen(tail)+1);
tail = strdup(".log");
}
break;
}
--len;
}
len=(int)strlen(base1);
if(len>0 && (base1[len-1]!='/') && (base1[len-1]!='-') && (base1[len-1]!='_')) {
snprintf(f, FILE_STR_LEN, "%s_%s%s", base1,logdate,tail);
} else {
snprintf(f, FILE_STR_LEN, "%s%s%s", base1,logdate,tail);
}
turn_free(base1,strlen(base1)+1);
turn_free(tail,strlen(tail)+1);
}
static void set_rtpfile(void)
{
if(to_syslog) {
return;
} else if (!_rtpfile) {
if(log_fn_base[0]) {
if(!strcmp(log_fn_base,"syslog")) {
_rtpfile = stdout;
to_syslog = 1;
} else if(!strcmp(log_fn_base,"stdout")|| !strcmp(log_fn_base,"-")) {
_rtpfile = stdout;
no_stdout_log = 1;
} else {
set_log_file_name(log_fn_base,log_fn);
_rtpfile = fopen(log_fn, "w");
if(_rtpfile)
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", log_fn);
}
if (!_rtpfile) {
fprintf(stderr,"ERROR: Cannot open log file for writing: %s\n",log_fn);
} else {
return;
}
}
}
if(!_rtpfile) {
char logbase[FILE_STR_LEN];
char logtail[FILE_STR_LEN];
char logf[FILE_STR_LEN];
if(simple_log)
snprintf(logtail, FILE_STR_LEN, "turn.log");
else
snprintf(logtail, FILE_STR_LEN, "turn_%d_", (int)getpid());
snprintf(logbase, FILE_STR_LEN, "/var/log/turnserver/%s", logtail);
set_log_file_name(logbase, logf);
_rtpfile = fopen(logf, "w");
if(_rtpfile)
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", logf);
else {
snprintf(logbase, FILE_STR_LEN, "/var/log/%s", logtail);
set_log_file_name(logbase, logf);
_rtpfile = fopen(logf, "w");
if(_rtpfile)
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", logf);
else {
snprintf(logbase, FILE_STR_LEN, "/var/tmp/%s", logtail);
set_log_file_name(logbase, logf);
_rtpfile = fopen(logf, "w");
if(_rtpfile)
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", logf);
else {
snprintf(logbase, FILE_STR_LEN, "/tmp/%s", logtail);
set_log_file_name(logbase, logf);
_rtpfile = fopen(logf, "w");
if(_rtpfile)
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", logf);
else {
snprintf(logbase, FILE_STR_LEN, "%s", logtail);
set_log_file_name(logbase, logf);
_rtpfile = fopen(logf, "w");
if(_rtpfile)
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", logf);
else {
_rtpfile = stdout;
return;
}
}
}
}
}
STRCPY(log_fn_base,logbase);
STRCPY(log_fn,logf);
}
}
void set_log_to_syslog(int val)
{
to_syslog = val;
}
void set_simple_log(int val)
{
simple_log = val;
}
#define Q(x) #x
#define QUOTE(x) Q(x)
void rollover_logfile(void)
{
if(to_syslog || !(log_fn[0]))
return;
{
FILE *f = fopen(log_fn,"r");
if(!f) {
fprintf(stderr, "log file is damaged\n");
reset_rtpprintf();
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file reopened: %s\n", log_fn);
return;
} else {
fclose(f);
}
}
if(simple_log)
return;
log_lock();
if(_rtpfile && log_fn[0] && (_rtpfile != stdout)) {
char logf[FILE_STR_LEN];
set_log_file_name(log_fn_base,logf);
if(strcmp(log_fn,logf)) {
fclose(_rtpfile);
log_fn[0]=0;
_rtpfile = fopen(logf, "w");
if(_rtpfile) {
STRCPY(log_fn,logf);
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", log_fn);
} else {
_rtpfile = stdout;
}
}
}
log_unlock();
}
static int get_syslog_level(TURN_LOG_LEVEL level)
{
switch(level) {
case TURN_LOG_LEVEL_CONTROL:
return LOG_NOTICE;
case TURN_LOG_LEVEL_WARNING:
return LOG_WARNING;
case TURN_LOG_LEVEL_ERROR:
return LOG_ERR;
default:
;
};
return LOG_INFO;
}
int vrtpprintf(TURN_LOG_LEVEL level, const char *format, va_list args)
{
/* 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;
if(to_syslog) {
syslog(get_syslog_level(level),"%s",s);
} else {
log_lock();
set_rtpfile();
if(fprintf(_rtpfile,"%s",s)<0) {
reset_rtpprintf();
} else if(fflush(_rtpfile)<0) {
reset_rtpprintf();
}
log_unlock();
}
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 ///////////////////
int get_default_protocol_port(const char* scheme, size_t slen)
{
if(scheme && (slen>0)) {
switch(slen) {
case 3:
if(!memcmp("ftp",scheme,3))
return 21;
if(!memcmp("svn",scheme,3))
return 3690;
if(!memcmp("ssh",scheme,4))
return 22;
if(!memcmp("sip",scheme,3))
return 5060;
break;
case 4:
if(!memcmp("http",scheme,4))
return 80;
if(!memcmp("ldap",scheme,4))
return 389;
if(!memcmp("sips",scheme,4))
return 5061;
if(!memcmp("turn",scheme,4))
return 3478;
if(!memcmp("stun",scheme,4))
return 3478;
break;
case 5:
if(!memcmp("https",scheme,5))
return 443;
if(!memcmp("ldaps",scheme,5))
return 636;
if(!memcmp("turns",scheme,5))
return 5349;
if(!memcmp("stuns",scheme,5))
return 5349;
break;
case 6:
if(!memcmp("telnet",scheme,6))
return 23;
if(!memcmp("radius",scheme,6))
return 1645;
break;
case 7:
if(!memcmp("svn+ssh",scheme,7))
return 22;
break;
default:
return 0;
};
}
return 0;
}
int get_canonic_origin(const char* o, char *co, int sz)
{
int ret = -1;
if(o && o[0] && co) {
co[0]=0;
struct evhttp_uri *uri = evhttp_uri_parse(o);
if(uri) {
const char *scheme = evhttp_uri_get_scheme(uri);
if(scheme && scheme[0]) {
size_t schlen = strlen(scheme);
if((schlen<(size_t)sz) && (schlen<STUN_MAX_ORIGIN_SIZE)) {
const char *host = evhttp_uri_get_host(uri);
if(host && host[0]) {
char otmp[STUN_MAX_ORIGIN_SIZE+STUN_MAX_ORIGIN_SIZE];
ns_bcopy(scheme,otmp,schlen);
otmp[schlen]=0;
{
char *s = otmp;
while(*s) {
*s = (char)tolower(*s);
++s;
}
}
int port = evhttp_uri_get_port(uri);
if(port<1) {
port = get_default_protocol_port(otmp, schlen);
}
if(port>0)
snprintf(otmp+schlen,sizeof(otmp)-schlen-1,"://%s:%d",host,port);
else
snprintf(otmp+schlen,sizeof(otmp)-schlen-1,"://%s",host);
{
char *s = otmp + schlen + 3;
while(*s) {
*s = (char)tolower(*s);
++s;
}
}
strncpy(co,otmp,sz);
co[sz]=0;
ret = 0;
}
}
}
evhttp_uri_free(uri);
}
}
if(ret<0) {
strncpy(co,o,sz);
co[sz]=0;
}
return ret;
}
//////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,86 @@
/*
* Copyright (C) 2011, 2012, 2013 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_ULIB__
#define __TURN_ULIB__
#if !defined(TURN_LOG_FUNC)
#define TURN_LOG_FUNC turn_log_func_default
#endif
#include "ns_turn_ioaddr.h"
#include <event2/http.h>
#ifdef __cplusplus
extern "C" {
#endif
//////////////////////// LOG //////////////////////////
typedef enum {
TURN_LOG_LEVEL_INFO = 0,
TURN_LOG_LEVEL_CONTROL,
TURN_LOG_LEVEL_WARNING,
TURN_LOG_LEVEL_ERROR
} TURN_LOG_LEVEL;
#define TURN_VERBOSE_NONE (0)
#define TURN_VERBOSE_NORMAL (1)
#define TURN_VERBOSE_EXTRA (2)
#define eve(v) ((v)==TURN_VERBOSE_EXTRA)
void set_no_stdout_log(int val);
void set_log_to_syslog(int val);
void set_simple_log(int val);
void turn_log_func_default(TURN_LOG_LEVEL level, const s08bits* format, ...);
void addr_debug_print(int verbose, const ioa_addr *addr, const s08bits* s);
/* Log */
extern volatile int _log_time_value_set;
extern volatile turn_time_t _log_time_value;
void rtpprintf(const char *format, ...);
int vrtpprintf(TURN_LOG_LEVEL level, const char *format, va_list args);
void reset_rtpprintf(void);
void set_logfile(const char *fn);
void rollover_logfile(void);
///////////////////////////////////////////////////////
#ifdef __cplusplus
}
#endif
#endif //__TURN_ULIB__

View File

@ -0,0 +1,252 @@
/*
* Copyright (C) 2011, 2012, 2013 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 "stun_buffer.h"
////////////////////// BUFFERS ///////////////////////////
int stun_init_buffer(stun_buffer *buf) {
if(!buf) return -1;
ns_bzero(buf->buf,sizeof(buf->buf));
buf->len=0;
buf->offset=0;
buf->coffset=0;
return 0;
}
int stun_get_size(const stun_buffer *buf) {
if(!buf) return 0;
return sizeof(buf->buf);
}
////////////////////////////////////////////////////////////
void stun_tid_from_message(const stun_buffer *buf, stun_tid* id) {
stun_tid_from_message_str(buf->buf,(size_t)(buf->len), id);
}
void stun_tid_generate_in_message(stun_buffer* buf, stun_tid* id) {
if(buf) {
stun_tid_generate_in_message_str(buf->buf, id);
}
}
////////////////////////////////////////////////////////
static inline int is_channel_msg(const stun_buffer* buf) {
if(buf && buf->len>0) {
return is_channel_msg_str(buf->buf, (size_t)(buf->len));
}
return 0;
}
int stun_is_command_message(const stun_buffer* buf) {
if(!buf || buf->len<=0)
return 0;
else
return stun_is_command_message_str(buf->buf,(size_t)(buf->len));
}
int stun_is_request(const stun_buffer* buf) {
return stun_is_request_str(buf->buf,(size_t)buf->len);
}
int stun_is_success_response(const stun_buffer* buf) {
return stun_is_success_response_str(buf->buf, (size_t)(buf->len));
}
int stun_is_error_response(const stun_buffer* buf, int *err_code, u08bits *err_msg, size_t err_msg_size) {
return stun_is_error_response_str(buf->buf, (size_t)(buf->len), err_code, err_msg, err_msg_size);
}
int stun_is_response(const stun_buffer* buf) {
return stun_is_response_str(buf->buf,(size_t)(buf->len));
}
int stun_is_indication(const stun_buffer* buf) {
if(is_channel_msg(buf)) return 0;
return IS_STUN_INDICATION(stun_get_msg_type(buf));
}
u16bits stun_get_method(const stun_buffer* buf) {
return stun_get_method_str(buf->buf, (size_t)(buf->len));
}
u16bits stun_get_msg_type(const stun_buffer* buf) {
if(!buf) return (u16bits)-1;
return stun_get_msg_type_str(buf->buf,(size_t)buf->len);
}
////////////////////////////////////////////////////////////
static void stun_init_command(u16bits message_type, stun_buffer* buf) {
buf->len=stun_get_size(buf);
stun_init_command_str(message_type, buf->buf, (size_t*)(&(buf->len)));
}
void stun_init_request(u16bits method, stun_buffer* buf) {
stun_init_command(stun_make_request(method), buf);
}
void stun_init_indication(u16bits method, stun_buffer* buf) {
stun_init_command(stun_make_indication(method), buf);
}
void stun_init_success_response(u16bits method, stun_buffer* buf, stun_tid* id) {
buf->len=stun_get_size(buf);
stun_init_success_response_str(method, buf->buf, (size_t*)(&(buf->len)), id);
}
void stun_init_error_response(u16bits method, stun_buffer* buf, u16bits error_code, const u08bits *reason, stun_tid* id) {
buf->len=stun_get_size(buf);
stun_init_error_response_str(method, buf->buf, (size_t*)(&(buf->len)), error_code, reason, id);
}
///////////////////////////////////////////////////////////////////////////////
int stun_get_command_message_len(const stun_buffer* buf) {
return stun_get_command_message_len_str(buf->buf, (size_t)(buf->len));
}
///////////////////////////////////////////////////////////////////////////////
int stun_init_channel_message(u16bits chnumber, stun_buffer* buf, int length, int do_padding) {
return stun_init_channel_message_str(chnumber, buf->buf, (size_t*)(&(buf->len)), length, do_padding);
}
int stun_is_channel_message(stun_buffer* buf, u16bits* chnumber, int is_padding_mandatory) {
if(!buf) return 0;
size_t blen = (size_t)buf->len;
int ret = stun_is_channel_message_str(buf->buf, &blen, chnumber, is_padding_mandatory);
if(ret) {
buf->len=(ssize_t)blen;
}
return ret;
}
///////////////////////////////////////////////////////////////////////////////
int stun_set_allocate_request(stun_buffer* buf, u32bits lifetime, int address_family, u08bits transport, int mobile) {
return stun_set_allocate_request_str(buf->buf, (size_t*)(&(buf->len)), lifetime, address_family, transport, mobile);
}
int stun_set_allocate_response(stun_buffer* buf, stun_tid* tid,
const ioa_addr *relayed_addr, const ioa_addr *reflexive_addr,
u32bits lifetime, int error_code, const u08bits *reason,
u64bits reservation_token, char *mobile_id) {
return stun_set_allocate_response_str(buf->buf, (size_t*)(&(buf->len)), tid,
relayed_addr, reflexive_addr,
lifetime, error_code, reason,
reservation_token, mobile_id);
}
///////////////////////////////////////////////////////////////////////////////
u16bits stun_set_channel_bind_request(stun_buffer* buf,
const ioa_addr* peer_addr, u16bits channel_number) {
return stun_set_channel_bind_request_str(buf->buf,(size_t*)(&(buf->len)), peer_addr, channel_number);
}
void stun_set_channel_bind_response(stun_buffer* buf, stun_tid* tid, int error_code, const u08bits *reason) {
stun_set_channel_bind_response_str(buf->buf, (size_t*)(&(buf->len)), tid, error_code, reason);
}
////////////////////////////////////////////////////////////////
stun_attr_ref stun_attr_get_first(const stun_buffer* buf) {
return stun_attr_get_first_str(buf->buf, (size_t)(buf->len));
}
stun_attr_ref stun_attr_get_next(const stun_buffer* buf, stun_attr_ref prev) {
return stun_attr_get_next_str(buf->buf, (size_t)(buf->len), prev);
}
int stun_attr_add(stun_buffer* buf, u16bits attr, const s08bits* avalue, int alen) {
return stun_attr_add_str(buf->buf, (size_t*)(&(buf->len)), attr, (const u08bits *)avalue, alen);
}
int stun_attr_add_channel_number(stun_buffer* buf, u16bits chnumber) {
return stun_attr_add_channel_number_str(buf->buf, (size_t *)(&(buf->len)), chnumber);
}
int stun_attr_add_addr(stun_buffer *buf,u16bits attr_type, const ioa_addr* ca) {
return stun_attr_add_addr_str(buf->buf,(size_t*)(&(buf->len)), attr_type, ca);
}
int stun_attr_get_addr(const stun_buffer *buf, stun_attr_ref attr, ioa_addr* ca,
const ioa_addr *default_addr) {
return stun_attr_get_addr_str(buf->buf, (size_t)(buf->len), attr, ca, default_addr);
}
int stun_attr_get_first_addr(const stun_buffer *buf, u16bits attr_type, ioa_addr* ca,
const ioa_addr *default_addr) {
return stun_attr_get_first_addr_str(buf->buf, (size_t)(buf->len), attr_type, ca, default_addr);
}
int stun_attr_add_even_port(stun_buffer* buf, uint8_t value) {
if(value) value=0x80;
return stun_attr_add(buf,STUN_ATTRIBUTE_EVEN_PORT,(const s08bits*)&value,1);
}
u16bits stun_attr_get_first_channel_number(const stun_buffer *buf) {
return stun_attr_get_first_channel_number_str(buf->buf, (size_t)(buf->len));
}
stun_attr_ref stun_attr_get_first_by_type(const stun_buffer* buf, u16bits attr_type) {
return stun_attr_get_first_by_type_str(buf->buf, (size_t)(buf->len), attr_type);
}
///////////////////////////////////////////////////////////////////////////////
void stun_set_binding_request(stun_buffer* buf) {
stun_set_binding_request_str(buf->buf, (size_t*)(&(buf->len)));
}
int stun_set_binding_response(stun_buffer* buf, stun_tid* tid,
const ioa_addr *reflexive_addr, int error_code, const u08bits *reason) {
return stun_set_binding_response_str(buf->buf, (size_t*)(&(buf->len)), tid,
reflexive_addr, error_code, reason,
0,0);
}
void stun_prepare_binding_request(stun_buffer* buf) {
stun_set_binding_request_str(buf->buf, (size_t*)(&(buf->len)));
}
int stun_is_binding_response(const stun_buffer* buf) {
return stun_is_binding_response_str(buf->buf, (size_t)(buf->len));
}
///////////////////////////////////////////////////////

View File

@ -0,0 +1,131 @@
/*
* Copyright (C) 2011, 2012, 2013 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_STUN_BUF__
#define __TURN_STUN_BUF__
#include "ns_turn_msg.h"
#ifdef __cplusplus
extern "C" {
#endif
///////////////////////////////////////////////////////////////
typedef struct _stun_buffer {
u08bits channel[STUN_CHANNEL_HEADER_LENGTH];
u08bits buf[STUN_BUFFER_SIZE];
size_t len;
u16bits offset;
u08bits coffset;
} stun_buffer;
//////////////////////////////////////////////////////////////
int stun_init_buffer(stun_buffer *buf);
int stun_get_size(const stun_buffer *buf);
//////////////////////////////////////////////////////////////
void stun_tid_generate_in_message(stun_buffer* buf, stun_tid* id);
void stun_tid_from_message(const stun_buffer *buf, stun_tid* id);
///////////////////////////////////////////////////////////////
int stun_is_command_message(const stun_buffer* buf);
int stun_is_request(const stun_buffer* buf);
int stun_is_response(const stun_buffer* buf);
int stun_is_success_response(const stun_buffer* buf);
int stun_is_error_response(const stun_buffer* buf, int *err_code, u08bits *err_msg, size_t err_msg_size);
int stun_is_indication(const stun_buffer* buf);
u16bits stun_get_method(const stun_buffer* buf);
u16bits stun_get_msg_type(const stun_buffer* buf);
///////////////////////////////////////////////////////////////
void stun_init_request(u16bits method, stun_buffer* buf);
void stun_init_indication(u16bits method, stun_buffer* buf);
void stun_init_success_response(u16bits method, stun_buffer* buf, stun_tid* id);
void stun_init_error_response(u16bits method, stun_buffer* buf, u16bits error_code, const u08bits *reason, stun_tid* id);
///////////////////////////////////////////////////////////////
int stun_attr_add(stun_buffer* buf, u16bits attr, const s08bits* avalue, int alen);
int stun_attr_add_channel_number(stun_buffer* buf, u16bits chnumber);
int stun_attr_add_addr(stun_buffer *buf,u16bits attr_type, const ioa_addr* ca);
stun_attr_ref stun_attr_get_first(const stun_buffer* buf);
stun_attr_ref stun_attr_get_first_by_type(const stun_buffer* buf, u16bits attr_type);
stun_attr_ref stun_attr_get_next(const stun_buffer* buf, stun_attr_ref prev);
int stun_attr_get_addr(const stun_buffer *buf, stun_attr_ref attr, ioa_addr* ca, const ioa_addr *default_addr);
int stun_attr_add_even_port(stun_buffer* buf, uint8_t value);
int stun_attr_get_first_addr(const stun_buffer *buf, u16bits attr_type, ioa_addr* ca, const ioa_addr *default_addr);
u16bits stun_attr_get_first_channel_number(const stun_buffer *buf);
///////////////////////////////////////////////////////////////
int stun_get_command_message_len(const stun_buffer* buf);
///////////////////////////////////////////////////////////////
int stun_init_channel_message(u16bits chnumber, stun_buffer* buf, int length, int do_padding);
int stun_is_channel_message(stun_buffer* buf, u16bits* chnumber, int is_padding_madatory);
///////////////////////////////////////////////////////////////
int stun_set_allocate_request(stun_buffer* buf, u32bits lifetime, int address_family, u08bits transport, int mobile);
int stun_set_allocate_response(stun_buffer* buf, stun_tid* tid,
const ioa_addr *relayed_addr, const ioa_addr *reflexive_addr,
u32bits lifetime,
int error_code, const u08bits *reason,
u64bits reservation_token, char *mobile_id);
///////////////////////////////////////////////////////////////
void stun_set_binding_request(stun_buffer* buf);
int stun_set_binding_response(stun_buffer* buf, stun_tid* tid,
const ioa_addr *reflexive_addr, int error_code, const u08bits *reason);
void stun_prepare_binding_request(stun_buffer* buf);
int stun_is_binding_response(const stun_buffer* buf);
///////////////////////////////////////////////////////////////
u16bits stun_set_channel_bind_request(stun_buffer* buf, const ioa_addr* peer_addr, u16bits channel_number);
void stun_set_channel_bind_response(stun_buffer* buf, stun_tid* tid, int error_code, const u08bits *reason);
///////////////////////////////////////////////////////////////
#ifdef __cplusplus
}
#endif
#endif //__TURN_STUN_BUF__

View File

@ -0,0 +1,102 @@
/*
* Copyright (C) 2011, 2012, 2013 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 "ns_turn_utils.h"
#include "udpserver.h"
#include "apputils.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
//////////////// local definitions /////////////////
static char Usage[] =
"Usage: server [options]\n"
"Options:\n"
" -p Listening UDP port (Default: 3480)\n"
" -d Listening interface device (optional)\n"
" -L Listening address\n"
" -v verbose\n";
//////////////////////////////////////////////////
int main(int argc, char **argv)
{
int port = PEER_DEFAULT_PORT;
char **local_addr_list=NULL;
size_t las = 0;
int verbose = TURN_VERBOSE_NONE;
int c;
char ifname[1025] = "\0";
IS_TURN_SERVER = 1;
set_logfile("stdout");
set_system_parameters(0);
while ((c = getopt(argc, argv, "d:p:L:v")) != -1)
switch (c){
case 'd':
STRCPY(ifname, optarg);
break;
case 'p':
port = atoi(optarg);
break;
case 'L':
local_addr_list = (char**)realloc(local_addr_list,++las*sizeof(char*));
local_addr_list[las-1]=strdup(optarg);
break;
case 'v':
verbose = TURN_VERBOSE_NORMAL;
break;
default:
fprintf(stderr, "%s\n", Usage);
exit(1);
}
if(las<1) {
local_addr_list = (char**)realloc(local_addr_list,++las*sizeof(char*));
local_addr_list[las-1]=strdup("0.0.0.0");
local_addr_list = (char**)realloc(local_addr_list,++las*sizeof(char*));
local_addr_list[las-1]=strdup("::");
}
server_type* server = start_udp_server(verbose, ifname, local_addr_list, las, port);
run_udp_server(server);
clean_udp_server(server);
return 0;
}

172
src/apps/peer/udpserver.c Normal file
View File

@ -0,0 +1,172 @@
/*
* Copyright (C) 2011, 2012, 2013 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 "apputils.h"
#include "udpserver.h"
#include "stun_buffer.h"
/////////////// io handlers ///////////////////
static void udp_server_input_handler(evutil_socket_t fd, short what, void* arg) {
if(!(what&EV_READ)) return;
ioa_addr *addr = (ioa_addr*)arg;
int len = 0;
int slen = get_ioa_addr_len(addr);
stun_buffer buffer;
ioa_addr remote_addr;
do {
len = recvfrom(fd, buffer.buf, sizeof(buffer.buf)-1, 0, (struct sockaddr*) &remote_addr, (socklen_t*) &slen);
} while(len<0 && (errno==EINTR));
buffer.len=len;
if(len>=0) {
do {
len = sendto(fd, buffer.buf, buffer.len, 0, (const struct sockaddr*) &remote_addr, (socklen_t) slen);
} while (len < 0 && ((errno == EINTR) || (errno == ENOBUFS) || (errno == EAGAIN)));
}
}
///////////////////// operations //////////////////////////
static int udp_create_server_socket(server_type* server,
const char* ifname, const char *local_address, int port) {
FUNCSTART;
if(!server) return -1;
evutil_socket_t udp_fd = -1;
ioa_addr *server_addr = (ioa_addr*)turn_malloc(sizeof(ioa_addr));
STRCPY(server->ifname,ifname);
if(make_ioa_addr((const u08bits*)local_address, port, server_addr)<0) return -1;
udp_fd = socket(server_addr->ss.sa_family, SOCK_DGRAM, 0);
if (udp_fd < 0) {
perror("socket");
return -1;
}
if(sock_bind_to_device(udp_fd, (unsigned char*)server->ifname)<0) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot bind udp server socket to device %s\n",server->ifname);
}
set_sock_buf_size(udp_fd,UR_SERVER_SOCK_BUF_SIZE);
if(addr_bind(udp_fd,server_addr,1)<0) return -1;
socket_set_nonblocking(udp_fd);
struct event *udp_ev = event_new(server->event_base,udp_fd,EV_READ|EV_PERSIST,
udp_server_input_handler,server_addr);
event_add(udp_ev,NULL);
FUNCEND;
return 0;
}
static server_type* init_server(int verbose, const char* ifname, char **local_addresses, size_t las, int port) {
server_type* server=(server_type*)turn_malloc(sizeof(server_type));
if(!server) return server;
ns_bzero(server,sizeof(server_type));
server->verbose=verbose;
server->event_base = turn_event_base_new();
while(las) {
udp_create_server_socket(server, ifname, local_addresses[--las], port);
udp_create_server_socket(server, ifname, local_addresses[las], port+1);
}
return server;
}
static int clean_server(server_type* server) {
if(server) {
if(server->event_base) event_base_free(server->event_base);
turn_free(server,sizeof(server_type));
}
return 0;
}
///////////////////////////////////////////////////////////
static void run_events(server_type* server) {
if(!server) return;
struct timeval timeout;
timeout.tv_sec=0;
timeout.tv_usec=100000;
event_base_loopexit(server->event_base, &timeout);
event_base_dispatch(server->event_base);
}
/////////////////////////////////////////////////////////////
server_type* start_udp_server(int verbose, const char* ifname, char **local_addresses, size_t las, int port) {
return init_server(verbose, ifname, local_addresses, las, port);
}
void run_udp_server(server_type* server) {
if(server) {
unsigned int cycle=0;
while (1) {
cycle++;
run_events(server);
}
}
}
void clean_udp_server(server_type* server) {
if(server) clean_server(server);
}
//////////////////////////////////////////////////////////////////

76
src/apps/peer/udpserver.h Normal file
View File

@ -0,0 +1,76 @@
/*
* Copyright (C) 2011, 2012, 2013 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 __UDP_SERVER__
#define __UDP_SERVER__
//////////////////////////////
#include "ns_turn_utils.h"
#include <event2/event.h>
#ifdef __cplusplus
extern "C" {
#endif
//////////////////////////////
struct server_info;
typedef struct server_info server_type;
///////////////////////////////////////////////////
#define FUNCSTART if(server && server->verbose) turn_log_func_default(TURN_LOG_LEVEL_INFO,"%s:%d:start\n",__FUNCTION__,__LINE__)
#define FUNCEND if(server && server->verbose) turn_log_func_default(TURN_LOG_LEVEL_INFO,"%s:%d:end\n",__FUNCTION__,__LINE__)
///////////////////////////////////////////////////////
struct server_info {
char ifname[1025];
struct event_base* event_base;
int verbose;
};
//////////////////////////////
server_type* start_udp_server(int verbose, const char* ifname, char **local_addresses, size_t las, int port);
void run_udp_server(server_type* server);
void clean_udp_server(server_type* server);
///////////////////////////////////////////
#ifdef __cplusplus
}
#endif
#endif //__UDP_SERVER__

View File

@ -0,0 +1,954 @@
/*
* Copyright (C) 2011, 2012, 2013 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 "apputils.h"
#include "mainrelay.h"
#include "dtls_listener.h"
#include "ns_ioalib_impl.h"
#include <openssl/ssl.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <pthread.h>
/* #define REQUEST_CLIENT_CERT */
///////////////////////////////////////////////////
#define FUNCSTART if(server && eve(server->verbose)) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s:%d:start\n",__FUNCTION__,__LINE__)
#define FUNCEND if(server && eve(server->verbose)) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s:%d:end\n",__FUNCTION__,__LINE__)
#define COOKIE_SECRET_LENGTH (32)
#define MAX_SINGLE_UDP_BATCH (16)
struct dtls_listener_relay_server_info {
char ifname[1025];
ioa_addr addr;
ioa_engine_handle e;
turn_turnserver *ts;
int verbose;
SSL_CTX *dtls_ctx;
struct event *udp_listen_ev;
ioa_socket_handle udp_listen_s;
ur_addr_map *children_ss; /* map of socket children on remote addr */
struct message_to_relay sm;
int slen0;
ioa_engine_new_connection_event_handler connect_cb;
};
///////////// forward declarations ////////
static int create_server_socket(dtls_listener_relay_server_type* server, int report_creation);
static int clean_server(dtls_listener_relay_server_type* server);
static int reopen_server_socket(dtls_listener_relay_server_type* server, evutil_socket_t fd);
///////////// dtls message types //////////
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 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);
}
int is_dtls_data_message(const unsigned char* buf, int len) {
return (buf && len>3 && buf[0]==0x17 && buf[1]==0xfe && buf[2]==0xff);
}
int is_dtls_alert_message(const unsigned char* buf, int len) {
return (buf && len>3 && buf[0]==0x15 && buf[1]==0xfe && buf[2]==0xff);
}
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);
}
int is_dtls_message(const unsigned char* buf, int len) {
if(buf && (len>3) && (buf[1])==0xfe && (buf[2]==0xff)) {
switch (buf[0]) {
case 0x14:
case 0x15:
case 0x16:
case 0x17:
return 1;
default:
;
}
}
return 0;
}
///////////// utils /////////////////////
#if !defined(TURN_NO_DTLS)
static void calculate_cookie(SSL* ssl, unsigned char *cookie_secret, unsigned int cookie_length) {
long rv=(long)ssl;
long inum=(cookie_length-(((long)cookie_secret)%sizeof(long)))/sizeof(long);
long i=0;
long *ip=(long*)cookie_secret;
for(i=0;i<inum;++i,++ip) *ip=rv;
}
static int generate_cookie(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)
{
unsigned char *buffer, result[EVP_MAX_MD_SIZE];
unsigned int length = 0, resultlength;
ioa_addr peer;
unsigned char cookie_secret[COOKIE_SECRET_LENGTH];
calculate_cookie(ssl, cookie_secret, sizeof(cookie_secret));
/* Read peer information */
(void) BIO_dgram_get_peer(SSL_get_wbio(ssl), &peer);
/* Create buffer with peer's address and port */
length = 0;
switch (peer.ss.sa_family) {
case AF_INET:
length += sizeof(struct in_addr);
break;
case AF_INET6:
length += sizeof(struct in6_addr);
break;
default:
OPENSSL_assert(0);
break;
}
length += sizeof(in_port_t);
buffer = (unsigned char*) OPENSSL_malloc(length);
if (buffer == NULL) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"out of memory\n");
return 0;
}
switch (peer.ss.sa_family) {
case AF_INET:
memcpy(buffer,
&peer.s4.sin_port,
sizeof(in_port_t));
memcpy(buffer + sizeof(peer.s4.sin_port),
&peer.s4.sin_addr,
sizeof(struct in_addr));
break;
case AF_INET6:
memcpy(buffer,
&peer.s6.sin6_port,
sizeof(in_port_t));
memcpy(buffer + sizeof(in_port_t),
&peer.s6.sin6_addr,
sizeof(struct in6_addr));
break;
default:
OPENSSL_assert(0);
break;
}
/* Calculate HMAC of buffer using the secret */
HMAC(EVP_sha1(), (const void*) cookie_secret, COOKIE_SECRET_LENGTH,
(const unsigned char*) buffer, length, result, &resultlength);
OPENSSL_free(buffer);
memcpy(cookie, result, resultlength);
*cookie_len = resultlength;
return 1;
}
static int verify_cookie(SSL *ssl, unsigned char *cookie, unsigned int cookie_len)
{
unsigned int resultlength=0;
unsigned char result[COOKIE_SECRET_LENGTH];
generate_cookie(ssl, result, &resultlength);
if (cookie_len == resultlength && memcmp(result, cookie, resultlength) == 0) {
//TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s: cookies are OK, length=%u\n",__FUNCTION__,cookie_len);
return 1;
}
return 0;
}
/////////////// io handlers ///////////////////
static ioa_socket_handle dtls_accept_client_connection(
dtls_listener_relay_server_type* server,
ioa_socket_handle sock,
SSL *ssl,
ioa_addr *remote_addr, ioa_addr *local_addr,
ioa_network_buffer_handle nbh)
{
FUNCSTART;
if (!ssl)
return NULL;
int rc = ssl_read(sock->fd, ssl, nbh, server->verbose);
if (rc < 0)
return NULL;
addr_debug_print(server->verbose, remote_addr, "Accepted connection from");
ioa_socket_handle ioas = create_ioa_socket_from_ssl(server->e, sock, ssl, DTLS_SOCKET, CLIENT_SOCKET, remote_addr, local_addr);
if(ioas) {
ioas->listener_server = server;
addr_cpy(&(server->sm.m.sm.nd.src_addr),remote_addr);
server->sm.m.sm.nd.recv_ttl = TTL_IGNORE;
server->sm.m.sm.nd.recv_tos = TOS_IGNORE;
server->sm.m.sm.s = ioas;
} else {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot create ioa_socket from SSL\n");
}
FUNCEND ;
return ioas;
}
static ioa_socket_handle dtls_server_input_handler(dtls_listener_relay_server_type* server,
ioa_socket_handle s,
ioa_network_buffer_handle nbh)
{
FUNCSTART;
if (!server || !nbh) {
return NULL;
}
SSL* connecting_ssl = NULL;
BIO *wbio = NULL;
struct timeval timeout;
/* Create BIO */
wbio = BIO_new_dgram(s->fd, BIO_NOCLOSE);
(void)BIO_dgram_set_peer(wbio, (struct sockaddr*) &(server->sm.m.sm.nd.src_addr));
/* Set and activate timeouts */
timeout.tv_sec = DTLS_MAX_RECV_TIMEOUT;
timeout.tv_usec = 0;
BIO_ctrl(wbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
connecting_ssl = SSL_new(server->dtls_ctx);
SSL_set_accept_state(connecting_ssl);
SSL_set_bio(connecting_ssl, NULL, wbio);
SSL_set_options(connecting_ssl, SSL_OP_COOKIE_EXCHANGE);
SSL_set_max_cert_list(connecting_ssl, 655350);
ioa_socket_handle rc = dtls_accept_client_connection(server, s, connecting_ssl,
&(server->sm.m.sm.nd.src_addr),
&(server->addr),
nbh);
if (!rc) {
if (!(SSL_get_shutdown(connecting_ssl) & SSL_SENT_SHUTDOWN)) {
SSL_set_shutdown(connecting_ssl, SSL_RECEIVED_SHUTDOWN);
SSL_shutdown(connecting_ssl);
}
SSL_free(connecting_ssl);
}
return rc;
}
#endif
static int handle_udp_packet(dtls_listener_relay_server_type *server,
struct message_to_relay *sm,
ioa_engine_handle ioa_eng, turn_turnserver *ts)
{
int verbose = ioa_eng->verbose;
ioa_socket_handle s = sm->m.sm.s;
ur_addr_map_value_type mvt = 0;
if(!(server->children_ss)) {
server->children_ss = (ur_addr_map*)allocate_super_memory_engine(server->e, sizeof(ur_addr_map));
ur_addr_map_init(server->children_ss);
}
ur_addr_map *amap = server->children_ss;
ioa_socket_handle chs = NULL;
if ((ur_addr_map_get(amap, &(sm->m.sm.nd.src_addr), &mvt) > 0) && mvt) {
chs = (ioa_socket_handle) mvt;
}
if (chs && !ioa_socket_tobeclosed(chs)
&& (chs->sockets_container == amap)
&& (chs->magic == SOCKET_MAGIC)) {
s = chs;
sm->m.sm.s = s;
if(s->ssl) {
int sslret = ssl_read(s->fd, s->ssl, sm->m.sm.nd.nbh, verbose);
if(sslret < 0) {
ioa_network_buffer_delete(ioa_eng, sm->m.sm.nd.nbh);
sm->m.sm.nd.nbh = NULL;
ts_ur_super_session *ss = (ts_ur_super_session *) s->session;
if (ss) {
turn_turnserver *server = (turn_turnserver *) ss->server;
if (server) {
shutdown_client_connection(server, ss, 0, "SSL read error");
}
} else {
close_ioa_socket(s);
}
ur_addr_map_del(amap, &(sm->m.sm.nd.src_addr), NULL);
sm->m.sm.s = NULL;
s = NULL;
chs = NULL;
} else if(ioa_network_buffer_get_size(sm->m.sm.nd.nbh)>0) {
;
} else {
ioa_network_buffer_delete(ioa_eng, sm->m.sm.nd.nbh);
sm->m.sm.nd.nbh = NULL;
}
}
if (s && s->read_cb && sm->m.sm.nd.nbh) {
s->e = ioa_eng;
s->read_cb(s, IOA_EV_READ, &(sm->m.sm.nd), s->read_ctx);
ioa_network_buffer_delete(ioa_eng, sm->m.sm.nd.nbh);
sm->m.sm.nd.nbh = NULL;
if (ioa_socket_tobeclosed(s)) {
ts_ur_super_session *ss = (ts_ur_super_session *) s->session;
if (ss) {
turn_turnserver *server = (turn_turnserver *) ss->server;
if (server) {
shutdown_client_connection(server, ss, 0, "UDP packet processing error");
}
}
}
}
} else {
if (chs && ioa_socket_tobeclosed(chs)) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
"%s: socket to be closed\n", __FUNCTION__);
{
u08bits saddr[129];
u08bits rsaddr[129];
long thrid = (long) pthread_self();
addr_to_string(get_local_addr_from_ioa_socket(chs),saddr);
addr_to_string(get_remote_addr_from_ioa_socket(chs),rsaddr);
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,
"%s: 111.111: thrid=0x%lx: Amap = 0x%lx, socket container=0x%lx, local addr %s, remote addr %s, s=0x%lx, done=%d, tbc=%d\n",
__FUNCTION__, thrid, (long) amap,
(long) (chs->sockets_container), (char*) saddr,
(char*) rsaddr, (long) s, (int) (chs->done),
(int) (chs->tobeclosed));
}
}
if (chs && (chs->magic != SOCKET_MAGIC)) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
"%s: wrong socket magic\n", __FUNCTION__);
}
if (chs && (chs->sockets_container != amap)) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
"%s: wrong socket container\n", __FUNCTION__);
{
u08bits saddr[129];
u08bits rsaddr[129];
long thrid = (long) pthread_self();
addr_to_string(get_local_addr_from_ioa_socket(chs),saddr);
addr_to_string(get_remote_addr_from_ioa_socket(chs),rsaddr);
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,
"%s: 111.222: thrid=0x%lx: Amap = 0x%lx, socket container=0x%lx, local addr %s, remote addr %s, s=0x%lx, done=%d, tbc=%d, st=%d, sat=%d\n",
__FUNCTION__, thrid, (long) amap,
(long) (chs->sockets_container), (char*) saddr,
(char*) rsaddr, (long) chs, (int) (chs->done),
(int) (chs->tobeclosed), (int) (chs->st),
(int) (chs->sat));
}
}
chs = NULL;
#if !defined(TURN_NO_DTLS)
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))) {
chs = dtls_server_input_handler(server,s, sm->m.sm.nd.nbh);
ioa_network_buffer_delete(server->e, sm->m.sm.nd.nbh);
sm->m.sm.nd.nbh = NULL;
}
#endif
if(!chs) {
chs = create_ioa_socket_from_fd(ioa_eng, s->fd, s,
UDP_SOCKET, CLIENT_SOCKET, &(sm->m.sm.nd.src_addr),
get_local_addr_from_ioa_socket(s));
}
s = chs;
sm->m.sm.s = s;
if (s) {
if(verbose) {
u08bits saddr[129];
u08bits rsaddr[129];
addr_to_string(get_local_addr_from_ioa_socket(s),saddr);
addr_to_string(get_remote_addr_from_ioa_socket(s),rsaddr);
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,
"%s: New UDP endpoint: local addr %s, remote addr %s\n",
__FUNCTION__, (char*) saddr,(char*) rsaddr);
}
s->e = ioa_eng;
s->listener_server = server;
add_socket_to_map(s, amap);
open_client_connection_session(ts, &(sm->m.sm));
}
}
return 0;
}
static int create_new_connected_udp_socket(
dtls_listener_relay_server_type* server, ioa_socket_handle s)
{
evutil_socket_t udp_fd = socket(s->local_addr.ss.sa_family, SOCK_DGRAM, 0);
if (udp_fd < 0) {
perror("socket");
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Cannot allocate new socket\n",
__FUNCTION__);
return -1;
}
if (sock_bind_to_device(udp_fd, (unsigned char*) (s->e->relay_ifname))
< 0) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
"Cannot bind udp server socket to device %s\n",
(char*) (s->e->relay_ifname));
}
ioa_socket_handle ret = (ioa_socket*) turn_malloc(sizeof(ioa_socket));
if (!ret) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
"%s: Cannot allocate new socket structure\n", __FUNCTION__);
close(udp_fd);
return -1;
}
ns_bzero(ret, sizeof(ioa_socket));
ret->magic = SOCKET_MAGIC;
ret->fd = udp_fd;
ret->family = s->family;
ret->st = s->st;
ret->sat = CLIENT_SOCKET;
ret->local_addr_known = 1;
addr_cpy(&(ret->local_addr), &(s->local_addr));
if (addr_bind(udp_fd,&(s->local_addr),1) < 0) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
"Cannot bind new detached udp server socket to local addr\n");
IOA_CLOSE_SOCKET(ret);
return -1;
}
ret->bound = 1;
{
int connect_err = 0;
if (addr_connect(udp_fd, &(server->sm.m.sm.nd.src_addr), &connect_err) < 0) {
char sl[129];
char sr[129];
addr_to_string(&(ret->local_addr),(u08bits*)sl);
addr_to_string(&(server->sm.m.sm.nd.src_addr),(u08bits*)sr);
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
"Cannot connect new detached udp client socket from local addr %s to remote addr %s\n",sl,sr);
IOA_CLOSE_SOCKET(ret);
return -1;
}
}
ret->connected = 1;
addr_cpy(&(ret->remote_addr), &(server->sm.m.sm.nd.src_addr));
set_socket_options(ret);
ret->current_ttl = s->current_ttl;
ret->default_ttl = s->default_ttl;
ret->current_tos = s->current_tos;
ret->default_tos = s->default_tos;
#if !defined(TURN_NO_DTLS)
if (!turn_params.no_dtls
&& is_dtls_handshake_message(
ioa_network_buffer_data(server->sm.m.sm.nd.nbh),
(int) ioa_network_buffer_get_size(
server->sm.m.sm.nd.nbh))) {
SSL* connecting_ssl = NULL;
BIO *wbio = NULL;
struct timeval timeout;
/* Create BIO */
wbio = BIO_new_dgram(ret->fd, BIO_NOCLOSE);
(void) BIO_dgram_set_peer(wbio, (struct sockaddr*) &(server->sm.m.sm.nd.src_addr));
BIO_ctrl(wbio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &(server->sm.m.sm.nd.src_addr));
/* Set and activate timeouts */
timeout.tv_sec = DTLS_MAX_RECV_TIMEOUT;
timeout.tv_usec = 0;
BIO_ctrl(wbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
connecting_ssl = SSL_new(server->dtls_ctx);
SSL_set_accept_state(connecting_ssl);
SSL_set_bio(connecting_ssl, NULL, wbio);
SSL_set_options(connecting_ssl, SSL_OP_COOKIE_EXCHANGE);
SSL_set_max_cert_list(connecting_ssl, 655350);
int rc = ssl_read(ret->fd, connecting_ssl, server->sm.m.sm.nd.nbh,
server->verbose);
if (rc < 0) {
if (!(SSL_get_shutdown(connecting_ssl) & SSL_SENT_SHUTDOWN)) {
SSL_set_shutdown(connecting_ssl, SSL_RECEIVED_SHUTDOWN);
SSL_shutdown(connecting_ssl);
}
SSL_free(connecting_ssl);
IOA_CLOSE_SOCKET(ret);
return -1;
}
addr_debug_print(server->verbose, &(server->sm.m.sm.nd.src_addr),
"Accepted DTLS connection from");
ret->ssl = connecting_ssl;
ret->listener_server = server;
ioa_network_buffer_delete(server->e, server->sm.m.sm.nd.nbh);
server->sm.m.sm.nd.nbh = NULL;
}
#endif
server->sm.m.sm.s = ret;
return server->connect_cb(server->e, &(server->sm));
}
static void udp_server_input_handler(evutil_socket_t fd, short what, void* arg)
{
int cycle = 0;
ioa_socket_handle s = (ioa_socket_handle)arg;
dtls_listener_relay_server_type* server = (dtls_listener_relay_server_type*)s->listener_server;
FUNCSTART;
if (!(what & EV_READ)) {
return;
}
//printf_server_socket(server, fd);
ioa_network_buffer_handle *elem = NULL;
start_udp_cycle:
elem = (ioa_network_buffer_handle *)ioa_network_buffer_allocate(server->e);
server->sm.m.sm.nd.nbh = elem;
server->sm.m.sm.nd.recv_ttl = TTL_IGNORE;
server->sm.m.sm.nd.recv_tos = TOS_IGNORE;
addr_set_any(&(server->sm.m.sm.nd.src_addr));
int slen = server->slen0;
ssize_t bsize = 0;
int flags = 0;
do {
bsize = recvfrom(fd, ioa_network_buffer_data(elem), ioa_network_buffer_get_capacity_udp(), flags, (struct sockaddr*) &(server->sm.m.sm.nd.src_addr), (socklen_t*) &slen);
} while (bsize < 0 && (errno == EINTR));
int conn_reset = is_connreset();
int to_block = would_block();
if (bsize < 0) {
if(to_block) {
ioa_network_buffer_delete(server->e, server->sm.m.sm.nd.nbh);
server->sm.m.sm.nd.nbh = NULL;
FUNCEND;
return;
}
#if defined(MSG_ERRQUEUE)
//Linux
int eflags = MSG_ERRQUEUE | MSG_DONTWAIT;
static s08bits buffer[65535];
u32bits errcode = 0;
ioa_addr orig_addr;
int ttl = 0;
int tos = 0;
udp_recvfrom(fd, &orig_addr, &(server->addr), buffer,
(int) sizeof(buffer), &ttl, &tos, server->e->cmsg, eflags,
&errcode);
//try again...
do {
bsize = recvfrom(fd, ioa_network_buffer_data(elem), ioa_network_buffer_get_capacity_udp(), flags, (struct sockaddr*) &(server->sm.m.sm.nd.src_addr), (socklen_t*) &slen);
} while (bsize < 0 && (errno == EINTR));
conn_reset = is_connreset();
to_block = would_block();
#endif
if(conn_reset) {
ioa_network_buffer_delete(server->e, server->sm.m.sm.nd.nbh);
server->sm.m.sm.nd.nbh = NULL;
reopen_server_socket(server,fd);
FUNCEND;
return;
}
}
if(bsize<0) {
if(!to_block && !conn_reset) {
int ern=errno;
perror(__FUNCTION__);
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: recvfrom error %d\n",__FUNCTION__,ern);
}
ioa_network_buffer_delete(server->e, server->sm.m.sm.nd.nbh);
server->sm.m.sm.nd.nbh = NULL;
FUNCEND;
return;
}
if (bsize > 0) {
int rc = 0;
ioa_network_buffer_set_size(elem, (size_t)bsize);
if(server->connect_cb) {
rc = create_new_connected_udp_socket(server, s);
if(rc<0) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot handle UDP packet, size %d\n",(int)bsize);
}
} else {
server->sm.m.sm.s = s;
rc = handle_udp_packet(server, &(server->sm), server->e, server->ts);
}
if(rc < 0) {
if(eve(server->e->verbose)) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot handle UDP event\n");
}
}
}
ioa_network_buffer_delete(server->e, server->sm.m.sm.nd.nbh);
server->sm.m.sm.nd.nbh = NULL;
if((bsize>0) && (cycle++<MAX_SINGLE_UDP_BATCH))
goto start_udp_cycle;
FUNCEND;
}
///////////////////// operations //////////////////////////
static int create_server_socket(dtls_listener_relay_server_type* server, int report_creation) {
FUNCSTART;
if(!server) return -1;
clean_server(server);
{
ioa_socket_raw udp_listen_fd = -1;
udp_listen_fd = socket(server->addr.ss.sa_family, SOCK_DGRAM, 0);
if (udp_listen_fd < 0) {
perror("socket");
return -1;
}
server->udp_listen_s = create_ioa_socket_from_fd(server->e, udp_listen_fd, NULL, UDP_SOCKET, LISTENER_SOCKET, NULL, &(server->addr));
server->udp_listen_s->listener_server = server;
set_sock_buf_size(udp_listen_fd,UR_SERVER_SOCK_BUF_SIZE);
if(sock_bind_to_device(udp_listen_fd, (unsigned char*)server->ifname)<0) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot bind listener socket to device %s\n",server->ifname);
}
{
const int max_binding_time = 60;
int addr_bind_cycle = 0;
retry_addr_bind:
if(addr_bind(udp_listen_fd,&server->addr,1)<0) {
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);
if(addr_bind_cycle++<max_binding_time) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Trying to bind UDP/DTLS listener socket to addr %s, again...\n",saddr);
sleep(1);
goto retry_addr_bind;
}
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Fatal final failure: cannot bind UDP/DTLS listener socket to addr %s\n",saddr);
exit(-1);
}
}
server->udp_listen_ev = event_new(server->e->event_base,udp_listen_fd,
EV_READ|EV_PERSIST,udp_server_input_handler,
server->udp_listen_s);
event_add(server->udp_listen_ev,NULL);
}
if(report_creation) {
if(!turn_params.no_udp && !turn_params.no_dtls)
addr_debug_print(server->verbose, &server->addr,"UDP/DTLS 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)
addr_debug_print(server->verbose, &server->addr,"UDP listener opened on");
}
FUNCEND;
return 0;
}
static int reopen_server_socket(dtls_listener_relay_server_type* server, evutil_socket_t fd)
{
UNUSED_ARG(fd);
if(!server)
return 0;
FUNCSTART;
{
EVENT_DEL(server->udp_listen_ev);
if(server->udp_listen_s->fd>=0) {
socket_closesocket(server->udp_listen_s->fd);
server->udp_listen_s->fd = -1;
}
if (!(server->udp_listen_s)) {
return create_server_socket(server,1);
}
ioa_socket_raw udp_listen_fd = socket(server->addr.ss.sa_family, SOCK_DGRAM, 0);
if (udp_listen_fd < 0) {
perror("socket");
FUNCEND;
return -1;
}
server->udp_listen_s->fd = udp_listen_fd;
/* some UDP sessions may fail due to the race condition here */
set_socket_options(server->udp_listen_s);
set_sock_buf_size(udp_listen_fd, UR_SERVER_SOCK_BUF_SIZE);
if (sock_bind_to_device(udp_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(udp_listen_fd,&server->addr,1)<0) {
perror("Cannot bind local socket to addr");
char saddr[129];
addr_to_string(&server->addr,(u08bits*)saddr);
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot bind listener socket to addr %s\n",saddr);
return -1;
}
server->udp_listen_ev = event_new(server->e->event_base, udp_listen_fd,
EV_READ | EV_PERSIST, udp_server_input_handler,
server->udp_listen_s);
event_add(server->udp_listen_ev, NULL );
}
if (!turn_params.no_udp && !turn_params.no_dtls)
addr_debug_print(server->verbose, &server->addr,
"UDP/DTLS 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)
addr_debug_print(server->verbose, &server->addr,
"UDP listener opened on ");
FUNCEND;
return 0;
}
#if defined(REQUEST_CLIENT_CERT)
static int dtls_verify_callback (int ok, X509_STORE_CTX *ctx) {
/* This function should ask the user
* if he trusts the received certificate.
* Here we always trust.
*/
if(ok && ctx) return 1;
return -1;
}
#endif
static int init_server(dtls_listener_relay_server_type* server,
const char* ifname,
const char *local_address,
int port,
int verbose,
ioa_engine_handle e,
turn_turnserver *ts,
int report_creation,
ioa_engine_new_connection_event_handler send_socket) {
if(!server) return -1;
server->dtls_ctx = e->dtls_ctx;
server->ts = ts;
server->connect_cb = send_socket;
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);
return -1;
}
server->slen0 = get_ioa_addr_len(&(server->addr));
server->verbose=verbose;
server->e = e;
if(server->dtls_ctx) {
#if defined(REQUEST_CLIENT_CERT)
/* If client has to authenticate, then */
SSL_CTX_set_verify(server->dtls_ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, dtls_verify_callback);
#endif
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
}
return create_server_socket(server, report_creation);
}
static int clean_server(dtls_listener_relay_server_type* server) {
if(server) {
EVENT_DEL(server->udp_listen_ev);
close_ioa_socket(server->udp_listen_s);
server->udp_listen_s = NULL;
}
return 0;
}
///////////////////////////////////////////////////////////
dtls_listener_relay_server_type* create_dtls_listener_server(const char* ifname,
const char *local_address,
int port,
int verbose,
ioa_engine_handle e,
turn_turnserver *ts,
int report_creation,
ioa_engine_new_connection_event_handler send_socket) {
dtls_listener_relay_server_type* server=(dtls_listener_relay_server_type*)
allocate_super_memory_engine(e,sizeof(dtls_listener_relay_server_type));
if(init_server(server,
ifname, local_address, port,
verbose,
e, ts, report_creation, send_socket)<0) {
return NULL;
} else {
return server;
}
}
ioa_engine_handle get_engine(dtls_listener_relay_server_type* server)
{
if(server)
return server->e;
return NULL;
}
//////////// UDP send ////////////////
void udp_send_message(dtls_listener_relay_server_type *server, ioa_network_buffer_handle nbh, ioa_addr *dest)
{
if(server && dest && nbh && (server->udp_listen_s))
udp_send(server->udp_listen_s, dest, (s08bits*)ioa_network_buffer_data(nbh), (int)ioa_network_buffer_get_size(nbh));
}
//////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,72 @@
/*
* Copyright (C) 2011, 2012, 2013 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 __DTLS_LISTENER__
#define __DTLS_LISTENER__
#include "ns_turn_utils.h"
#include "ns_ioalib_impl.h"
#include "ns_turn_server.h"
#include <event2/event.h>
#ifdef __cplusplus
extern "C" {
#endif
///////////////////////////////////////////
struct dtls_listener_relay_server_info;
typedef struct dtls_listener_relay_server_info dtls_listener_relay_server_type;
///////////////////////////////////////////
dtls_listener_relay_server_type* create_dtls_listener_server(const char* ifname,
const char *local_address,
int port,
int verbose,
ioa_engine_handle e,
turn_turnserver *ts,
int report_creation,
ioa_engine_new_connection_event_handler send_socket);
void udp_send_message(dtls_listener_relay_server_type *server, ioa_network_buffer_handle nbh, ioa_addr *dest);
ioa_engine_handle get_engine(dtls_listener_relay_server_type* server);
///////////////////////////////////////////
#ifdef __cplusplus
}
#endif
#endif //__DTLS_LISTENER__

1545
src/apps/relay/libtelnet.c Normal file

File diff suppressed because it is too large Load Diff

677
src/apps/relay/libtelnet.h Normal file
View File

@ -0,0 +1,677 @@
/*!
* \brief libtelnet - TELNET protocol handling library
*
* SUMMARY:
*
* libtelnet is a library for handling the TELNET protocol. It includes
* routines for parsing incoming data from a remote peer as well as formatting
* data to send to the remote peer.
*
* libtelnet uses a callback-oriented API, allowing application-specific
* handling of various events. The callback system is also used for buffering
* outgoing protocol data, allowing the application to maintain control over
* the actual socket connection.
*
* Features supported include the full TELNET protocol, Q-method option
* negotiation, ZMP, MCCP2, MSSP, and NEW-ENVIRON.
*
* CONFORMS TO:
*
* RFC854 - http://www.faqs.org/rfcs/rfc854.html
* RFC855 - http://www.faqs.org/rfcs/rfc855.html
* RFC1091 - http://www.faqs.org/rfcs/rfc1091.html
* RFC1143 - http://www.faqs.org/rfcs/rfc1143.html
* RFC1408 - http://www.faqs.org/rfcs/rfc1408.html
* RFC1572 - http://www.faqs.org/rfcs/rfc1572.html
*
* LICENSE:
*
* The author or authors of this code dedicate any and all copyright interest
* in this code to the public domain. We make this dedication for the benefit
* of the public at large and to the detriment of our heirs and successors. We
* intend this dedication to be an overt act of relinquishment in perpetuity of
* all present and future rights to this code under copyright law.
*
* \file libtelnet.h
*
* \version 0.21
*
* \author Sean Middleditch <sean@sourcemud.org>
*/
/**
* Minor fixes by Oleg Moskalenko
*/
#if !defined(LIBTELNET_INCLUDE)
#define LIBTELNET_INCLUDE 1
/* standard C headers necessary for the libtelnet API */
#include <stdarg.h>
/* C++ support */
#if defined(__cplusplus)
extern "C" {
#endif
/* printf type checking feature in GCC and some other compilers */
#if __GNUC__
# define TELNET_GNU_PRINTF(f,a) __attribute__((format(printf, f, a))) /*!< internal helper */
#else
# define TELNET_GNU_PRINTF(f,a) /*!< internal helper */
#endif
/*! Telnet state tracker object type. */
typedef struct telnet_t telnet_t;
/*! Telnet event object type. */
typedef union telnet_event_t telnet_event_t;
/*! Telnet option table element type. */
typedef struct telnet_telopt_t telnet_telopt_t;
/*! \name Telnet commands */
/*@{*/
/*! Telnet commands and special values. */
#define TELNET_IAC 255
#define TELNET_DONT 254
#define TELNET_DO 253
#define TELNET_WONT 252
#define TELNET_WILL 251
#define TELNET_SB 250
#define TELNET_GA 249
#define TELNET_EL 248
#define TELNET_EC 247
#define TELNET_AYT 246
#define TELNET_AO 245
#define TELNET_IP 244
#define TELNET_BREAK 243
#define TELNET_DM 242
#define TELNET_NOP 241
#define TELNET_SE 240
#define TELNET_EOR 239
#define TELNET_ABORT 238
#define TELNET_SUSP 237
#define TELNET_EOF 236
/*@}*/
/*! \name Telnet option values. */
/*@{*/
/*! Telnet options. */
#define TELNET_TELOPT_BINARY 0
#define TELNET_TELOPT_ECHO 1
#define TELNET_TELOPT_RCP 2
#define TELNET_TELOPT_SGA 3
#define TELNET_TELOPT_NAMS 4
#define TELNET_TELOPT_STATUS 5
#define TELNET_TELOPT_TM 6
#define TELNET_TELOPT_RCTE 7
#define TELNET_TELOPT_NAOL 8
#define TELNET_TELOPT_NAOP 9
#define TELNET_TELOPT_NAOCRD 10
#define TELNET_TELOPT_NAOHTS 11
#define TELNET_TELOPT_NAOHTD 12
#define TELNET_TELOPT_NAOFFD 13
#define TELNET_TELOPT_NAOVTS 14
#define TELNET_TELOPT_NAOVTD 15
#define TELNET_TELOPT_NAOLFD 16
#define TELNET_TELOPT_XASCII 17
#define TELNET_TELOPT_LOGOUT 18
#define TELNET_TELOPT_BM 19
#define TELNET_TELOPT_DET 20
#define TELNET_TELOPT_SUPDUP 21
#define TELNET_TELOPT_SUPDUPOUTPUT 22
#define TELNET_TELOPT_SNDLOC 23
#define TELNET_TELOPT_TTYPE 24
#define TELNET_TELOPT_EOR 25
#define TELNET_TELOPT_TUID 26
#define TELNET_TELOPT_OUTMRK 27
#define TELNET_TELOPT_TTYLOC 28
#define TELNET_TELOPT_3270REGIME 29
#define TELNET_TELOPT_X3PAD 30
#define TELNET_TELOPT_NAWS 31
#define TELNET_TELOPT_TSPEED 32
#define TELNET_TELOPT_LFLOW 33
#define TELNET_TELOPT_LINEMODE 34
#define TELNET_TELOPT_XDISPLOC 35
#define TELNET_TELOPT_ENVIRON 36
#define TELNET_TELOPT_AUTHENTICATION 37
#define TELNET_TELOPT_ENCRYPT 38
#define TELNET_TELOPT_NEW_ENVIRON 39
#define TELNET_TELOPT_MSSP 70
#define TELNET_TELOPT_COMPRESS2 86
#define TELNET_TELOPT_ZMP 93
#define TELNET_TELOPT_EXOPL 255
#define TELNET_TELOPT_MCCP2 86
/*@}*/
/*! \name Protocol codes for TERMINAL-TYPE commands. */
/*@{*/
/*! TERMINAL-TYPE codes. */
#define TELNET_TTYPE_IS 0
#define TELNET_TTYPE_SEND 1
/*@}*/
/*! \name Protocol codes for NEW-ENVIRON/ENVIRON commands. */
/*@{*/
/*! NEW-ENVIRON/ENVIRON codes. */
#define TELNET_ENVIRON_IS 0
#define TELNET_ENVIRON_SEND 1
#define TELNET_ENVIRON_INFO 2
#define TELNET_ENVIRON_VAR 0
#define TELNET_ENVIRON_VALUE 1
#define TELNET_ENVIRON_ESC 2
#define TELNET_ENVIRON_USERVAR 3
/*@}*/
/*! \name Protocol codes for MSSP commands. */
/*@{*/
/*! MSSP codes. */
#define TELNET_MSSP_VAR 1
#define TELNET_MSSP_VAL 2
/*@}*/
/*! \name Telnet state tracker flags. */
/*@{*/
/*! Control behavior of telnet state tracker. */
#define TELNET_FLAG_PROXY (1<<0)
#define TELNET_PFLAG_DEFLATE (1<<7)
/*@}*/
#if !defined(UNUSED_ARG)
#define UNUSED_ARG(A) do { A=A; } while(0)
#endif
/*!
* error codes
*/
enum telnet_error_t {
TELNET_EOK = 0, /*!< no error */
TELNET_EBADVAL, /*!< invalid parameter, or API misuse */
TELNET_ENOMEM, /*!< memory allocation failure */
TELNET_EOVERFLOW, /*!< data exceeds buffer size */
TELNET_EPROTOCOL, /*!< invalid sequence of special bytes */
TELNET_ECOMPRESS /*!< error handling compressed streams */
};
typedef enum telnet_error_t telnet_error_t; /*!< Error code type. */
/*!
* event codes
*/
enum telnet_event_type_t {
TELNET_EV_DATA = 0, /*!< raw text data has been received */
TELNET_EV_SEND, /*!< data needs to be sent to the peer */
TELNET_EV_IAC, /*!< generic IAC code received */
TELNET_EV_WILL, /*!< WILL option negotiation received */
TELNET_EV_WONT, /*!< WONT option neogitation received */
TELNET_EV_DO, /*!< DO option negotiation received */
TELNET_EV_DONT, /*!< DONT option negotiation received */
TELNET_EV_SUBNEGOTIATION, /*!< sub-negotiation data received */
TELNET_EV_COMPRESS, /*!< compression has been enabled */
TELNET_EV_ZMP, /*!< ZMP command has been received */
TELNET_EV_TTYPE, /*!< TTYPE command has been received */
TELNET_EV_ENVIRON, /*!< ENVIRON command has been received */
TELNET_EV_MSSP, /*!< MSSP command has been received */
TELNET_EV_WARNING, /*!< recoverable error has occured */
TELNET_EV_ERROR /*!< non-recoverable error has occured */
};
typedef enum telnet_event_type_t telnet_event_type_t; /*!< Telnet event type. */
/*!
* environ/MSSP command information
*/
struct telnet_environ_t {
unsigned char type; /*!< either TELNET_ENVIRON_VAR or TELNET_ENVIRON_USERVAR */
const char *var; /*!< name of the variable being set */
const char *value; /*!< value of variable being set; empty string if no value */
};
/*!
* event information
*/
union telnet_event_t {
/*!
* \brief Event type
*
* The type field will determine which of the other event structure fields
* have been filled in. For instance, if the event type is TELNET_EV_ZMP,
* then the zmp event field (and ONLY the zmp event field) will be filled
* in.
*/
enum telnet_event_type_t type;
/*!
* data event: for DATA and SEND events
*/
struct data_t {
enum telnet_event_type_t _type; /*!< alias for type */
const char *buffer; /*!< byte buffer */
size_t size; /*!< number of bytes in buffer */
} data;
/*!
* WARNING and ERROR events
*/
struct error_t {
enum telnet_event_type_t _type; /*!< alias for type */
const char *file; /*!< file the error occured in */
const char *func; /*!< function the error occured in */
const char *msg; /*!< error message string */
int line; /*!< line of file error occured on */
telnet_error_t errcode; /*!< error code */
} error;
/*!
* command event: for IAC
*/
struct iac_t {
enum telnet_event_type_t _type; /*!< alias for type */
unsigned char cmd; /*!< telnet command received */
} iac;
/*!
* negotiation event: WILL, WONT, DO, DONT
*/
struct negotiate_t {
enum telnet_event_type_t _type; /*!< alias for type */
unsigned char telopt; /*!< option being negotiated */
} neg;
/*!
* subnegotiation event
*/
struct subnegotiate_t {
enum telnet_event_type_t _type; /*!< alias for type */
const char *buffer; /*!< data of sub-negotiation */
size_t size; /*!< number of bytes in buffer */
unsigned char telopt; /*!< option code for negotiation */
} sub;
/*!
* ZMP event
*/
struct zmp_t {
enum telnet_event_type_t _type; /*!< alias for type */
const char **argv; /*!< array of argument string */
size_t argc; /*!< number of elements in argv */
} zmp;
/*!
* TTYPE event
*/
struct ttype_t {
enum telnet_event_type_t _type; /*!< alias for type */
unsigned char cmd; /*!< TELNET_TTYPE_IS or TELNET_TTYPE_SEND */
const char* name; /*!< terminal type name (IS only) */
} ttype;
/*!
* COMPRESS event
*/
struct compress_t {
enum telnet_event_type_t _type; /*!< alias for type */
unsigned char state; /*!< 1 if compression is enabled,
0 if disabled */
} compress;
/*!
* ENVIRON/NEW-ENVIRON event
*/
struct environ_t {
enum telnet_event_type_t _type; /*!< alias for type */
const struct telnet_environ_t *values; /*!< array of variable values */
size_t size; /*!< number of elements in values */
unsigned char cmd; /*!< SEND, IS, or INFO */
} environ;
/*!
* MSSP event
*/
struct mssp_t {
enum telnet_event_type_t _type; /*!< alias for type */
const struct telnet_environ_t *values; /*!< array of variable values */
size_t size; /*!< number of elements in values */
} mssp;
};
/*!
* \brief event handler
*
* This is the type of function that must be passed to
* telnet_init() when creating a new telnet object. The
* function will be invoked once for every event generated
* by the libtelnet protocol parser.
*
* \param telnet The telnet object that generated the event
* \param event Event structure with details about the event
* \param user_data User-supplied pointer
*/
typedef void (*telnet_event_handler_t)(telnet_t *telnet,
telnet_event_t *event, void *user_data);
/*!
* telopt support table element; use telopt of -1 for end marker
*/
struct telnet_telopt_t {
short telopt; /*!< one of the TELOPT codes or -1 */
unsigned char us; /*!< TELNET_WILL or TELNET_WONT */
unsigned char him; /*!< TELNET_DO or TELNET_DONT */
};
/*!
* state tracker -- private data structure
*/
struct telnet_t;
/*!
* \brief Initialize a telnet state tracker.
*
* This function initializes a new state tracker, which is used for all
* other libtelnet functions. Each connection must have its own
* telnet state tracker object.
*
* \param telopts Table of TELNET options the application supports.
* \param eh Event handler function called for every event.
* \param flags 0 or TELNET_FLAG_PROXY.
* \param user_data Optional data pointer that will be passsed to eh.
* \return Telent state tracker object.
*/
extern telnet_t* telnet_init(const telnet_telopt_t *telopts,
telnet_event_handler_t eh, unsigned char flags, void *user_data);
/*!
* \brief Free up any memory allocated by a state tracker.
*
* This function must be called when a telnet state tracker is no
* longer needed (such as after the connection has been closed) to
* release any memory resources used by the state tracker.
*
* \param telnet Telnet state tracker object.
*/
extern void telnet_free(telnet_t *telnet);
/*!
* \brief Push a byte buffer into the state tracker.
*
* Passes one or more bytes to the telnet state tracker for
* protocol parsing. The byte buffer is most often going to be
* the buffer that recv() was called for while handling the
* connection.
*
* \param telnet Telnet state tracker object.
* \param buffer Pointer to byte buffer.
* \param size Number of bytes pointed to by buffer.
*/
extern void telnet_recv(telnet_t *telnet, const char *buffer,
size_t size);
/*!
* \brief Send a telnet command.
*
* \param telnet Telnet state tracker object.
* \param cmd Command to send.
*/
extern void telnet_iac(telnet_t *telnet, unsigned char cmd);
/*!
* \brief Send negotiation command.
*
* Internally, libtelnet uses RFC1143 option negotiation rules.
* The negotiation commands sent with this function may be ignored
* if they are determined to be redundant.
*
* \param telnet Telnet state tracker object.
* \param cmd TELNET_WILL, TELNET_WONT, TELNET_DO, or TELNET_DONT.
* \param opt One of the TELNET_TELOPT_* values.
*/
extern void telnet_negotiate(telnet_t *telnet, unsigned char cmd,
unsigned char opt);
/*!
* Send non-command data (escapes IAC bytes).
*
* \param telnet Telnet state tracker object.
* \param buffer Buffer of bytes to send.
* \param size Number of bytes to send.
*/
extern void telnet_send(telnet_t *telnet,
const char *buffer, size_t size);
/*!
* \brief Begin a sub-negotiation command.
*
* Sends IAC SB followed by the telopt code. All following data sent
* will be part of the sub-negotiation, until telnet_finish_sb() is
* called.
*
* \param telnet Telnet state tracker object.
* \param telopt One of the TELNET_TELOPT_* values.
*/
extern void telnet_begin_sb(telnet_t *telnet,
unsigned char telopt);
/*!
* \brief Finish a sub-negotiation command.
*
* This must be called after a call to telnet_begin_sb() to finish a
* sub-negotiation command.
*
* \param telnet Telnet state tracker object.
*/
#define telnet_finish_sb(telnet) telnet_iac((telnet), TELNET_SE)
/*!
* \brief Shortcut for sending a complete subnegotiation buffer.
*
* Equivalent to:
* telnet_begin_sb(telnet, telopt);
* telnet_send(telnet, buffer, size);
* telnet_finish_sb(telnet);
*
* \param telnet Telnet state tracker format.
* \param telopt One of the TELNET_TELOPT_* values.
* \param buffer Byte buffer for sub-negotiation data.
* \param size Number of bytes to use for sub-negotiation data.
*/
extern void telnet_subnegotiation(telnet_t *telnet, unsigned char telopt,
const char *buffer, size_t size);
/*!
* \brief Begin sending compressed data.
*
* This function will begein sending data using the COMPRESS2 option,
* which enables the use of zlib to compress data sent to the client.
* The client must offer support for COMPRESS2 with option negotiation,
* and zlib support must be compiled into libtelnet.
*
* Only the server may call this command.
*
* \param telnet Telnet state tracker object.
*/
extern void telnet_begin_compress2(telnet_t *telnet);
/*!
* \brief Send formatted data.
*
* This function is a wrapper around telnet_send(). It allows using
* printf-style formatting.
*
* Additionally, this function will translate \\r to the CR NUL construct and
* \\n with CR LF, as well as automatically escaping IAC bytes like
* telnet_send().
*
* \param telnet Telnet state tracker object.
* \param fmt Format string.
* \return Number of bytes sent.
*/
extern int telnet_printf(telnet_t *telnet, const char *fmt, ...)
TELNET_GNU_PRINTF(2, 3);
/*!
* \brief Send formatted data.
*
* See telnet_printf().
*/
extern int telnet_vprintf(telnet_t *telnet, const char *fmt, va_list va);
/*!
* \brief Send formatted data (no newline escaping).
*
* This behaves identically to telnet_printf(), except that the \\r and \\n
* characters are not translated. The IAC byte is still escaped as normal
* with telnet_send().
*
* \param telnet Telnet state tracker object.
* \param fmt Format string.
* \return Number of bytes sent.
*/
extern int telnet_raw_printf(telnet_t *telnet, const char *fmt, ...)
TELNET_GNU_PRINTF(2, 3);
/*!
* \brief Send formatted data (no newline escaping).
*
* See telnet_raw_printf().
*/
extern int telnet_raw_vprintf(telnet_t *telnet, const char *fmt, va_list va);
/*!
* \brief Begin a new set of NEW-ENVIRON values to request or send.
*
* This function will begin the sub-negotiation block for sending or
* requesting NEW-ENVIRON values.
*
* The telnet_finish_newenviron() macro must be called after this
* function to terminate the NEW-ENVIRON command.
*
* \param telnet Telnet state tracker object.
* \param type One of TELNET_ENVIRON_SEND, TELNET_ENVIRON_IS, or
* TELNET_ENVIRON_INFO.
*/
extern void telnet_begin_newenviron(telnet_t *telnet, unsigned char type);
/*!
* \brief Send a NEW-ENVIRON variable name or value.
*
* This can only be called between calls to telnet_begin_newenviron() and
* telnet_finish_newenviron().
*
* \param telnet Telnet state tracker object.
* \param type One of TELNET_ENVIRON_VAR, TELNET_ENVIRON_USERVAR, or
* TELNET_ENVIRON_VALUE.
* \param string Variable name or value.
*/
extern void telnet_newenviron_value(telnet_t* telnet, unsigned char type,
const char *string);
/*!
* \brief Finish a NEW-ENVIRON command.
*
* This must be called after a call to telnet_begin_newenviron() to finish a
* NEW-ENVIRON variable list.
*
* \param telnet Telnet state tracker object.
*/
#define telnet_finish_newenviron(telnet) telnet_finish_sb((telnet))
/*!
* \brief Send the TERMINAL-TYPE SEND command.
*
* Sends the sequence IAC TERMINAL-TYPE SEND.
*
* \param telnet Telnet state tracker object.
*/
extern void telnet_ttype_send(telnet_t *telnet);
/*!
* \brief Send the TERMINAL-TYPE IS command.
*
* Sends the sequence IAC TERMINAL-TYPE IS "string".
*
* According to the RFC, the recipient of a TERMINAL-TYPE SEND shall
* send the next possible terminal-type the client supports. Upon sending
* the type, the client should switch modes to begin acting as the terminal
* type is just sent.
*
* The server may continue sending TERMINAL-TYPE IS until it receives a
* terminal type is understands. To indicate to the server that it has
* reached the end of the available optoins, the client must send the last
* terminal type a second time. When the server receives the same terminal
* type twice in a row, it knows it has seen all available terminal types.
*
* After the last terminal type is sent, if the client receives another
* TERMINAL-TYPE SEND command, it must begin enumerating the available
* terminal types from the very beginning. This allows the server to
* scan the available types for a preferred terminal type and, if none
* is found, to then ask the client to switch to an acceptable
* alternative.
*
* Note that if the client only supports a single terminal type, then
* simply sending that one type in response to every SEND will satisfy
* the behavior requirements.
*
* \param telnet Telnet state tracker object.
* \param ttype Name of the terminal-type being sent.
*/
extern void telnet_ttype_is(telnet_t *telnet, const char* ttype);
/*!
* \brief Send a ZMP command.
*
* \param telnet Telnet state tracker object.
* \param argc Number of ZMP commands being sent.
* \param argv Array of argument strings.
*/
extern void telnet_send_zmp(telnet_t *telnet, size_t argc, const char **argv);
/*!
* \brief Send a ZMP command.
*
* Arguments are listed out in var-args style. After the last argument, a
* NULL pointer must be passed in as a sentinel value.
*
* \param telnet Telnet state tracker object.
*/
extern void telnet_send_zmpv(telnet_t *telnet, ...);
/*!
* \brief Send a ZMP command.
*
* See telnet_send_zmpv().
*/
extern void telnet_send_vzmpv(telnet_t *telnet, va_list va);
/*!
* \brief Begin sending a ZMP command
*
* \param telnet Telnet state tracker object.
* \param cmd The first argument (command name) for the ZMP command.
*/
extern void telnet_begin_zmp(telnet_t *telnet, const char *cmd);
/*!
* \brief Send a ZMP command argument.
*
* \param telnet Telnet state tracker object.
* \param arg Telnet argument string.
*/
extern void telnet_zmp_arg(telnet_t *telnet, const char *arg);
/*!
* \brief Finish a ZMP command.
*
* This must be called after a call to telnet_begin_zmp() to finish a
* ZMP argument list.
*
* \param telnet Telnet state tracker object.
*/
#define telnet_finish_zmp(telnet) telnet_finish_sb((telnet))
/* C++ support */
#if defined(__cplusplus)
} /* extern "C" */
#endif
#endif /* !defined(LIBTELNET_INCLUDE) */

Some files were not shown because too many files have changed in this diff Show More