1
0
mirror of https://github.com/coturn/coturn.git synced 2026-05-09 12:46:09 +02:00

Merge tag 'upstream/4.5.0.7'

Upstream version 4.5.0.7
This commit is contained in:
Oleg Moskalenko 2017-12-10 20:06:29 -08:00
commit 06741d1351
21 changed files with 785 additions and 370 deletions

View File

@ -1,9 +1,15 @@
12/10/2017 Oleg Moskalenko <mom040267@gmail.com>
Version 4.5.0.7 'dan Eider':
- Misc security improvements.
10/17/2016 Oleg Moskalenko <mom040267@gmail.com>
Version 4.5.0.6 'dan Eider':
- Typos in the text fixed.
- TLS1.2 support fixed.
- uclient minor performance tweak.
- Issue #113 fixed (by David Benjamin)
- Report total traffic used per allocation via Redis (by Bradley T. Hughes)
- Add the realm parameter in the example config file (by Domenico)
08/27/2016 Oleg Moskalenko <mom040267@gmail.com>
Version 4.5.0.5 'dan Eider':

11
Dockerfile.build Normal file
View File

@ -0,0 +1,11 @@
FROM ubuntu:16.04
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
emacs-nox \
build-essential \
libssl-dev sqlite3 \
libsqlite3-dev \
libevent-dev \
g++ \
libboost-dev \
libevent-dev

View File

@ -1,41 +1,41 @@
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.
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/
The compiled binary image of this program is located in bin/
sub-directory.
2. turnutils_peer: a simple stateless UDP-only "echo" server,
to be used as the final server in relay pattern ("peer"). For every incoming
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
(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.
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
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
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
5. turnutils_natdiscovery: a utility that provides NAT behavior discovery
according RFC5780. This utility discovers the actual NAT Mapping and Filtering
behavior. Be aweare that at least two different listening IP addresses should
be configured to be able to work properly!
5. turnutils_natdiscovery: a utility that provides NAT behavior discovery
according RFC5780. This utility discovers the actual NAT Mapping and Filtering
behavior, etc. Be aware that on TURN server side two different listening IP
addresses should be configured to be able to work properly!
6. turnutils_oauth: a utility that provides OAuth access_token
generation(AEAD encryption), validation and decryption. This utility inputs
@ -49,34 +49,34 @@ script in examples/scripts/oauth.sh.
=====================================
NAME
turnutils_uclient - this client emulation application is supplied for the test purposes only.
SYNOPSIS
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.
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.
The number of the messages to send is configurable.
Flags:
Flags:
-t Use TCP for communications between client and TURN server (default is UDP).
-b Use SCTP for communications between client and TURN server (default is UDP).
-T Use TCP for the relay transport (default - UDP). Implies options -t, -y, -c,
-T Use TCP for the relay transport (default - UDP). Implies options -t, -y, -c,
and ignores flags and options -s, -e, -r and -g. Can be used together
with -b.
-P Passive TCP (RFC6062 with active peer). Implies -T.
-S Secure SSL connection: SSL/TLS for TCP, DTLS for UDP, TLS/SCTP for SCTP.
@ -87,11 +87,11 @@ Flags:
-s Use "Send" method in TURN; by default, it uses TURN Channels.
-y Use client-to-client connections:
-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.
@ -109,12 +109,12 @@ Flags:
-R do negative protocol tests.
-O DOS attack mode.
-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).
-B Random disconnect after a few initial packets.
@ -123,7 +123,7 @@ Flags:
-J Use oAuth with default test key kid='north'.
Options with required values:
Options with required values:
-l Message length (Default: 100 Bytes).
@ -159,7 +159,7 @@ Options with required values:
table in the database if dynamic, or the static-auth-secret
value set in the configuration file if using static.
-C This is the timestamp/username separator symbol (character) in
-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.
@ -171,23 +171,23 @@ Options with required values:
See the examples in the "examples/scripts" directory.
======================================
NAME
turnutils_peer - a simple UDP-only echo backend server.
turnutils_peer - a simple UDP-only echo backend server.
SYNOPSIS
$ 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:
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.
@ -198,50 +198,50 @@ If no listener address(es) defined, then it listens on all IPv4 and IPv6 address
========================================
NAME
turnutils_stunclient - a basic STUN client.
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:
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
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.
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
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:
Usage:
$ turnutils_rfc5769check
@ -249,7 +249,7 @@ $ turnutils_rfc5769check
NAME
turnutils_natdiscovery - a utility that discovers NAT mapping and filtering
turnutils_natdiscovery - a utility that discovers NAT mapping and filtering
behavior according RFC5780.
SYNOPSIS
@ -258,13 +258,13 @@ $ turnutils_natdiscovery [options] <STUN-Server-FQDN-or-IP-address>
DESCRIPTION
turnutils_natdiscovery discovers the NAT Mapping and Filtering behavior, to
determine if that NAT is currently using Endpoint-Independent,
Address-Dependent, or Address and Port-Dependent Mapping and/or to determine if
that NAT is currently using Endpoint-Independent, Address-Dependent, or Address
and Port-Dependent Filtering.
turnutils_natdiscovery discovers the NAT Mapping and Filtering behavior, to
determine if that NAT is currently using Endpoint-Independent,
Address-Dependent, or Address and Port-Dependent Mapping and/or to determine if
that NAT is currently using Endpoint-Independent, Address-Dependent, or Address
and Port-Dependent Filtering.
Use either -m and/or -f flag to discover NAT Mapping and/or Filtering.
Use either -m, -f, -c, -H flag to discover NAT behavior.
Flags:
@ -272,12 +272,30 @@ Flags:
-f NAT filtering behavior discovery
-t NAT mapping lifetime behavior discovery
Requires a timer (-T)
-c NAT collision behavior discovery
-H NAT hairpinning behavior discovery
-P Add 1500 byte Padding to the behavior discovery
Applicable with all except NAT mapping Lifetime discovery
Options with required values:
-p STUN server port (Default: 3478)
-L Local address to use (optional)
-l Local port to use (use with -L)
-A Secondary Local address (optional)
Required for collision discovery
-T Mapping lifetime timer (sec)
Used by mapping lifetime behavior discovery
Usage:
$ turnutils_natdiscovery -m -f stun.example.com
@ -351,7 +369,7 @@ Usage:
$ turnutils_natdiscovery
===================================
DOCS
After installation, run the command:
@ -397,7 +415,7 @@ new STUN RFC 5389
TURN RFC 5766
TURN-TCP extension RFC 6062
TURN IPv6 extension RFC 6156
STUN/TURN test vectors RFC 5769
@ -443,17 +461,17 @@ SEE ALSO
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@acision.com>
Mutsutoshi Yoshimoto <mutsutoshi.yoshimoto@mixi.co.jp>
Federico Pinna <fpinna@vivocha.com>
Bradley T. Hughes <bradleythughes@fastmail.fm>
Mihaly Meszaros <bakfitty@gmail.com>
Mihaly Meszaros <bakfitty@gmail.com>

15
build-docker.sh Executable file
View File

@ -0,0 +1,15 @@
#!/bin/bash
set -o xtrace
dir=`pwd`
echo "$dir"
build_image=coturnbuild
dockerargs="--privileged -v ${dir}:/root/coturn -w /root/coturn"
container_env=' -e "INSIDECONTAINER=-incontainer=true"'
docker="docker run --rm -it ${dockerargs} ${container_env} ${build_image}"
docker build -f Dockerfile.build -t ${build_image} .
${docker} bash -c "./configure && make"

View File

@ -217,8 +217,15 @@
#
#oauth
#The default realm to be used for the users when no explicit origin/realm
#relationship was found in the database. Must be used with long-term
#credentials mechanism or with TURN REST API.
#
#realm=realm
# 'Static' user accounts for long term credentials mechanism, only.
# This option cannot be used with TURN REST API.
# This option require a realm.
# 'Static' user accounts are NOT dynamically checked by the turnserver process,
# so that they can NOT be changed while the turnserver is running.
#

View File

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

View File

@ -1,5 +1,5 @@
.\" Text automatically generated by txt2man
.TH TURN 1 "13 November 2016" "" ""
.TH TURN 1 "29 September 2017" "" ""
.SH GENERAL INFORMATION
The \fBTURN Server\fP project contains the source code of a TURN server and TURN client

View File

@ -1,41 +1,41 @@
.\" Text automatically generated by txt2man
.TH TURN 1 "13 November 2016" "" ""
.TH TURN 1 "29 September 2017" "" ""
.SH GENERAL INFORMATION
A set of turnutils_* programs provides some utility functionality to be used
for testing and for setting up the TURN server.
for testing and for setting up the TURN server.
.TP
.B
1.
\fIturnutils_uclient\fP: emulates multiple UDP,TCP,TLS or DTLS clients.
\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/
The compiled binary image of this program is located in bin/
sub\-directory.
.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
\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
(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.
\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
\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.
.PP
In the "examples/scripts" subdirectory, you will find the examples of command lines to be used
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
@ -44,10 +44,10 @@ $ ./scripts/secure_relay.sh
.TP
.B
5.
\fIturnutils_natdiscovery\fP: a utility that provides NAT behavior discovery
according RFC5780. This utility discovers the actual NAT Mapping and Filtering
behavior. Be aweare that at least two different listening IP addresses should
be configured to be able to work properly!
\fIturnutils_natdiscovery\fP: a utility that provides NAT behavior discovery
according RFC5780. This utility discovers the actual NAT Mapping and Filtering
behavior, etc. Be aware that on TURN server side two different listening IP
addresses should be configured to be able to work properly!
.TP
.B
6.
@ -69,19 +69,25 @@ script in examples/scripts/oauth.sh.
\fB
\fBturnutils_uclient \fP\- this client emulation application is supplied for the test purposes only.
\fB
.SS SYNOPSIS
.SS SYNOPSIS
.nf
.fam C
$ \fIturnutils_uclient\fP [\fB\-tTSvsyhcxg\fP] [options] <TURN\-Server\-IP\-address>
$ \fIturnutils_uclient\fP [\fB\-tTSvsyhcxg\fP] [\fIoptions\fP] <TURN\-Server\-IP\-address>
.fam T
.fi
.fam T
.fi
.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.
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.
The number of the messages to send is configurable.
.TP
.B
.PP
Flags:
.TP
.B
@ -94,8 +100,8 @@ Use SCTP for communications between client and TURN server (default is UDP).
.TP
.B
\fB\-T\fP
Use TCP for the relay transport (default \- UDP). Implies options \fB\-t\fP, \fB\-y\fP, \fB\-c\fP,
and ignores flags and options \fB\-s\fP, \fB\-e\fP, \fB\-r\fP and \fB\-g\fP. Can be used together
Use TCP for the relay transport (default \- UDP). Implies \fIoptions\fP \fB\-t\fP, \fB\-y\fP, \fB\-c\fP,
and ignores flags and \fIoptions\fP \fB\-s\fP, \fB\-e\fP, \fB\-r\fP and \fB\-g\fP. Can be used together
with \fB\-b\fP.
.TP
.B
@ -120,7 +126,7 @@ Use "Send" method in TURN; by default, it uses TURN Channels.
.TP
.B
\fB\-y\fP
Use client\-to\-client connections:
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.
@ -185,8 +191,7 @@ Dual allocation (SSODA). Implies \fB\-c\fP option.
.B
\fB\-J\fP
Use oAuth with default test key kid='north'.
.TP
.B
.PP
Options with required values:
.TP
.B
@ -224,7 +229,7 @@ Local IP address (optional).
.TP
.B
\fB\-m\fP
Number of clients (Default: 1, 2 or 4, depending on options).
Number of clients (Default: 1, 2 or 4, depending on \fIoptions\fP).
.TP
.B
\fB\-e\fP
@ -255,7 +260,7 @@ value set in the configuration file if using static.
.TP
.B
\fB\-C\fP
This is the timestamp/username separator symbol (character) in
This is the timestamp/username separator symbol (character) in
TURN REST API. The default value is :.
.TP
.B
@ -290,8 +295,7 @@ $ \fIturnutils_peer\fP [\fB\-v\fP] [\fIoptions\fP]
.SS DESCRIPTION
This application is used for the test purposes only, as a peer for the \fIturnutils_uclient\fP application.
.TP
.B
.PP
Options with required values:
.TP
.B
@ -329,8 +333,7 @@ $ \fIturnutils_stunclient\fP [\fIoptions\fP] <STUN\-Server\-IP\-address>
.SS DESCRIPTION
It sends a "new" STUN RFC 5389 request (over UDP) and shows the reply information.
.TP
.B
.PP
Options with required values:
.TP
.B
@ -345,9 +348,9 @@ Local address to use (optional).
\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
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).
@ -369,12 +372,11 @@ $ \fIturnutils_rfc5769check\fP
.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
\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
.PP
Usage:
.PP
$ \fIturnutils_rfc5769check\fP
@ -397,13 +399,13 @@ $ \fIturnutils_natdiscovery\fP [\fIoptions\fP] <STUN\-Server\-FQDN\-or\-IP\-addr
.fi
.SS DESCRIPTION
\fIturnutils_natdiscovery\fP discovers the NAT Mapping and Filtering behavior, to
determine if that NAT is currently using Endpoint\-Independent,
Address\-Dependent, or Address and Port\-Dependent Mapping and/or to determine if
that NAT is currently using Endpoint\-Independent, Address\-Dependent, or Address
and Port\-Dependent Filtering.
\fIturnutils_natdiscovery\fP discovers the NAT Mapping and Filtering behavior, to
determine if that NAT is currently using Endpoint\-Independent,
Address\-Dependent, or Address and Port\-Dependent Mapping and/or to determine if
that NAT is currently using Endpoint\-Independent, Address\-Dependent, or Address
and Port\-Dependent Filtering.
.PP
Use either \fB\-m\fP and/or \fB\-f\fP flag to discover NAT Mapping and/or Filtering.
Use either \fB\-m\fP, \fB\-f\fP, \fB\-c\fP, \fB\-H\fP flag to discover NAT behavior.
.PP
Flags:
.TP
@ -414,6 +416,24 @@ NAT mapping behavior discovery
.B
\fB\-f\fP
NAT filtering behavior discovery
.TP
.B
\fB\-t\fP
NAT mapping lifetime behavior discovery
Requires a timer (\fB\-T\fP)
.TP
.B
\fB\-c\fP
NAT collision behavior discovery
.TP
.B
\fB\-H\fP
NAT hairpinning behavior discovery
.TP
.B
\fB\-P\fP
Add 1500 byte Padding to the behavior discovery
Applicable with all except NAT mapping Lifetime discovery
.PP
Options with required values:
.TP
@ -424,6 +444,20 @@ STUN server port (Default: 3478)
.B
\fB\-L\fP
Local address to use (optional)
.TP
.B
\fB\-l\fP
Local port to use (use with \fB\-L\fP)
.TP
.B
\fB\-A\fP
Secondary Local address (optional)
Required for collision discovery
.TP
.B
\fB\-T\fP
Mapping lifetime timer (sec)
Used by mapping lifetime behavior discovery
.PP
Usage:
.PP
@ -635,5 +669,6 @@ Mutsutoshi Yoshimoto <mutsutoshi.yoshimoto@mixi.co.jp>
Federico Pinna <fpinna@vivocha.com>
.PP
Bradley T. Hughes <bradleythughes@fastmail.fm>
.RE
.PP
Mihaly Meszaros <bakfitty@gmail.com>

View File

@ -26,7 +26,7 @@ cd ${CPWD}
# Platform file
echo "CentOS7.2" > ${BUILDDIR}/platform
echo "CentOS7.4" > ${BUILDDIR}/platform
cp ${CPWD}/epel7.install.sh ${BUILDDIR}/install.sh

View File

@ -2,7 +2,7 @@
# Common settings script.
TURNVERSION=4.5.0.6
TURNVERSION=4.5.0.7
BUILDDIR=~/rpmbuild
ARCH=`uname -p`
TURNSERVER_GIT_URL=https://github.com/coturn/coturn.git

View File

@ -1,5 +1,5 @@
Name: turnserver
Version: 4.5.0.6
Version: 4.5.0.7
Release: 0%{dist}
Summary: Coturn TURN Server
@ -295,6 +295,8 @@ fi
%{_includedir}/turn/client/TurnMsgLib.h
%changelog
* Sun Dec 10 2017 Oleg Moskalenko <mom040267@gmail.com>
- Sync to 4.5.0.7
* Mon Oct 17 2016 Oleg Moskalenko <mom040267@gmail.com>
- Sync to 4.5.0.6
* Sat Aug 27 2016 Oleg Moskalenko <mom040267@gmail.com>

View File

@ -1,32 +1,32 @@
/*
* 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.
*/
* 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 <err.h>
#include <stdlib.h>
@ -44,38 +44,43 @@
#endif
////////////////////////////////////////////////////
static int udp_fd = -1;
static ioa_addr real_local_addr;
static int udp_fd2 = -1;
static int counter = 0;
#ifdef __cplusplus
static int run_stunclient(ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, int *port, int *rfc5780, int response_port, int change_ip, int change_port, int padding)
{
static int init_socket(int *socketfd, ioa_addr *local_addr, int local_port, ioa_addr *remote_addr){
int ret=0;
if (response_port >= 0) {
addr_set_port(&real_local_addr, response_port);
if (local_port >= 0) {
addr_set_port(local_addr, local_port);
}
udp_fd = socket(remote_addr->ss.sa_family, SOCK_DGRAM, 0);
*socketfd = socket(remote_addr->ss.sa_family, SOCK_DGRAM, 0);
if (udp_fd < 0)
err(-1, NULL);
err(-1, NULL);
if (!addr_any(&real_local_addr)) {
if (addr_bind(udp_fd, &real_local_addr,0,1,UDP_SOCKET) < 0)
err(-1, NULL);
if (!addr_any(local_addr)) {
if (addr_bind(*socketfd, local_addr,0,1,UDP_SOCKET) < 0)
err(-1, NULL);
}
return ret;
}
static int stunclient_send(int sockfd, ioa_addr *local_addr, int *local_port, ioa_addr *remote_addr, int change_ip, int change_port, int padding, int response_port){
int ret=0;
turn::StunMsgRequest req(STUN_METHOD_BINDING);
req.constructBindingRequest();
if (response_port >= 0) {
turn::StunAttrResponsePort rpa;
turn::StunAttrResponsePort rpa;
rpa.setResponsePort((u16bits)response_port);
try {
req.addAttr(rpa);
@ -129,20 +134,28 @@ static int run_stunclient(ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_a
int slen = get_ioa_addr_len(remote_addr);
do {
len = sendto(udp_fd, req.getRawBuffer(), req.getSize(), 0, (struct sockaddr*) remote_addr, (socklen_t) slen);
len = sendto(sockfd, req.getRawBuffer(), req.getSize(), 0, (struct sockaddr*) remote_addr, (socklen_t) slen);
} while (len < 0 && ((errno == EINTR) || (errno == ENOBUFS) || (errno == EAGAIN)));
if (len < 0)
err(-1, NULL);
err(-1, NULL);
}
if (addr_get_from_sock(udp_fd, &real_local_addr) < 0) {
if (addr_get_from_sock(sockfd, local_addr) < 0) {
printf("%s: Cannot get address from local socket\n", __FUNCTION__);
} else {
*port = addr_get_port(&real_local_addr);
*local_port = addr_get_port(local_addr);
}
return ret;
}
static int stunclient_receive(int sockfd, ioa_addr *local_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, int *rfc5780){
int ret=0;
{
int len = 0;
stun_buffer buf;
@ -154,10 +167,10 @@ static int run_stunclient(ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_a
tv.tv_sec = 3; /* 3 Secs Timeout */
tv.tv_usec = 0; // Not init'ing this can cause strange errors
setsockopt(udp_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval));
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval));
do {
len = recv(udp_fd, ptr, to_recv - recvd, 0);
len = recv(sockfd, ptr, to_recv - recvd, 0);
if (len > 0) {
recvd += len;
ptr += len;
@ -165,15 +178,19 @@ static int run_stunclient(ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_a
}
} while (len < 0 && (errno == EINTR));
if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
printf("STUN receive timeout..\n");
ret = 1;
return ret;
}
if (recvd > 0)
len = recvd;
len = recvd;
buf.len = len;
try {
turn::StunMsgResponse res(buf.buf, sizeof(buf.buf), (size_t)buf.len, true);
if (res.isCommand()) {
if(res.isSuccess()) {
if (res.isBindingResponse()) {
@ -189,19 +206,33 @@ static int run_stunclient(ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_a
*rfc5780 = 1;
printf("\n========================================\n");
printf("RFC 5780 response %d\n",++counter);
turn::StunAttrAddr addr1(iter1);
addr1.getAddr(*other_addr);
turn::StunAttrIterator iter2(res,STUN_ATTRIBUTE_RESPONSE_ORIGIN);
turn::StunAttrIterator iter2(res,STUN_ATTRIBUTE_MAPPED_ADDRESS);
if (!iter2.eof()) {
ioa_addr response_origin;
ioa_addr mapped_addr;
addr_set_any(&mapped_addr);
turn::StunAttrAddr addr2(iter2);
addr2.getAddr(response_origin);
addr2.getAddr(mapped_addr);
if (!addr_eq(&mapped_addr,reflexive_addr)){
printf("-= ALG detected! Mapped and XOR-Mapped differ! =-\n");
addr_debug_print(1, &mapped_addr, "Mapped Address: ");
} else {
printf("No ALG: Mapped == XOR-Mapped\n");
}
} else {
printf("Not received mapped address attribute!\n");
} turn::StunAttrAddr addr1(iter1);
addr1.getAddr(*other_addr);
turn::StunAttrIterator iter3(res,STUN_ATTRIBUTE_RESPONSE_ORIGIN);
if (!iter3.eof()) {
ioa_addr response_origin;
turn::StunAttrAddr addr3(iter3);
addr3.getAddr(response_origin);
addr_debug_print(1, &response_origin, "Response origin: ");
}
addr_debug_print(1, other_addr, "Other addr: ");
}
addr_debug_print(1, reflexive_addr, "UDP reflexive addr");
addr_debug_print(1, local_addr, "Local addr: ");
} else {
printf("Cannot read the response\n");
}
@ -218,50 +249,117 @@ static int run_stunclient(ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_a
printf("The response is not a reponse message\n");
}
} catch(...) {
if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
printf("STUN receive timeout..\n");
}else{
turn::StunMsgRequest msg(buf.buf, sizeof(buf.buf), (size_t)buf.len, true);
if (msg.isRequest(buf.buf,(size_t)buf.len)) {
printf("Received a request (maybe a successful hairpinning)\n");
return ret;
} else {
printf("The response is not a well formed STUN message\n");
}
ret=1;
ret=1;
}
}
return ret;
}
static int run_stunclient(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, int *local_port, int *rfc5780, int change_ip, int change_port, int padding){
int ret=0;
ret=init_socket(&udp_fd, local_addr, *local_port, remote_addr);
ret=stunclient_send(udp_fd, local_addr, local_port, remote_addr, change_ip, change_port, padding, -1);
ret=stunclient_receive(udp_fd, local_addr, reflexive_addr, other_addr, rfc5780);
close(udp_fd);
return ret;
}
static int run_stunclient_hairpinning(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, int *local_port, int *rfc5780, int change_ip, int change_port, int padding){
int ret=0;
init_socket(&udp_fd,local_addr,*local_port,remote_addr);
ret=stunclient_send(udp_fd, local_addr, local_port, remote_addr, change_ip, change_port, padding, -1);
ret=stunclient_receive(udp_fd, local_addr, reflexive_addr, other_addr, rfc5780);
addr_cpy(remote_addr,reflexive_addr);
addr_set_port(local_addr, 0);
init_socket(&udp_fd2,local_addr,0,remote_addr);
ret=stunclient_send(udp_fd2, local_addr, local_port, remote_addr, change_ip, change_port, padding, -1);
ret=stunclient_receive(udp_fd, local_addr, reflexive_addr, other_addr, rfc5780);
if(ret){
ret=stunclient_receive(udp_fd2, local_addr, reflexive_addr, other_addr, rfc5780);
}
close(udp_fd);
close(udp_fd2);
return ret;
}
static int run_stunclient_lifetime(int timer,ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, int *local_port, int *rfc5780, int change_ip, int change_port, int padding){
int ret=0;
int response_port;
init_socket(&udp_fd, local_addr, *local_port, remote_addr);
ret=stunclient_send(udp_fd, local_addr, local_port, remote_addr, change_ip, change_port, padding, -1);
ret=stunclient_receive(udp_fd, local_addr, reflexive_addr, other_addr, rfc5780);
addr_set_port(local_addr, 0);
sleep(timer);
init_socket(&udp_fd2,local_addr,0,remote_addr);
response_port=addr_get_port(reflexive_addr);
ret=stunclient_send(udp_fd2, local_addr, local_port, remote_addr, change_ip, change_port, padding, response_port);
ret=stunclient_receive(udp_fd, local_addr, reflexive_addr, other_addr, rfc5780);
socket_closesocket(udp_fd);
socket_closesocket(udp_fd2);
return ret;
}
#else
static int run_stunclient(ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, int *port, int *rfc5780, int response_port, int change_ip, int change_port, int padding)
{
static int init_socket(int *socketfd, ioa_addr *local_addr, int local_port, ioa_addr *remote_addr){
int ret=0;
stun_buffer buf;
udp_fd = socket(remote_addr->ss.sa_family, CLIENT_DGRAM_SOCKET_TYPE, CLIENT_DGRAM_SOCKET_PROTOCOL);
*socketfd = socket(remote_addr->ss.sa_family, CLIENT_DGRAM_SOCKET_TYPE, CLIENT_DGRAM_SOCKET_PROTOCOL);
if (udp_fd < 0)
err(-1, NULL);
err(-1, NULL);
if (!addr_any(&real_local_addr)) {
if (response_port >= 0) {
addr_set_port(&real_local_addr, response_port);
}
if (addr_bind(udp_fd, &real_local_addr,0,1,UDP_SOCKET) < 0) {
if (local_port >= 0) {
addr_set_port(local_addr, local_port);
}
if (!addr_any(local_addr)) {
if (addr_bind(*socketfd, local_addr,0,1,UDP_SOCKET) < 0) {
err(-1, NULL);
}
}
}
return ret;
}
stun_prepare_binding_request(&buf);
static int stunclient_send(stun_buffer *buf, int sockfd, ioa_addr *local_addr, int *local_port, ioa_addr *remote_addr, int change_ip, int change_port, int padding, int response_port){
int ret=0;
stun_prepare_binding_request(buf);
if (response_port >= 0) {
stun_attr_add_response_port_str((u08bits*) (buf.buf), (size_t*) &(buf.len), (u16bits) response_port);
stun_attr_add_response_port_str((u08bits*) (buf->buf), (size_t*) &(buf->len), (u16bits) response_port);
}
if (change_ip || change_port) {
stun_attr_add_change_request_str((u08bits*) buf.buf, (size_t*) &(buf.len), change_ip, change_port);
stun_attr_add_change_request_str((u08bits*) buf->buf, (size_t*) &(buf->len), change_ip, change_port);
}
if (padding) {
if(stun_attr_add_padding_str((u08bits*) buf.buf, (size_t*) &(buf.len), 1500)<0) {
if(stun_attr_add_padding_str((u08bits*) buf->buf, (size_t*) &(buf->len), 1500)<0) {
printf("%s: ERROR: Cannot add padding\n",__FUNCTION__);
}
}
@ -271,35 +369,42 @@ static int run_stunclient(ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_a
int slen = get_ioa_addr_len(remote_addr);
do {
len = sendto(udp_fd, buf.buf, buf.len, 0, (struct sockaddr*) remote_addr, (socklen_t) slen);
len = sendto(sockfd, buf->buf, buf->len, 0, (struct sockaddr*) remote_addr, (socklen_t) slen);
} while (len < 0 && ((errno == EINTR) || (errno == ENOBUFS) || (errno == EAGAIN)));
if (len < 0)
err(-1, NULL);
err(-1, NULL);
}
if (addr_get_from_sock(udp_fd, &real_local_addr) < 0) {
if (addr_get_from_sock(sockfd, local_addr) < 0) {
printf("%s: Cannot get address from local socket\n", __FUNCTION__);
} else {
*port = addr_get_port(&real_local_addr);
*local_port = addr_get_port(local_addr);
}
return ret;
}
static int stunclient_receive(stun_buffer *buf, int sockfd, ioa_addr *local_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, int *rfc5780){
int ret=0;
{
int len = 0;
u08bits *ptr = buf.buf;
u08bits *ptr = buf->buf;
int recvd = 0;
const int to_recv = sizeof(buf.buf);
const int to_recv = sizeof(buf->buf);
struct timeval tv;
tv.tv_sec = 3; /* 3 Secs Timeout */
tv.tv_usec = 0; // Not init'ing this can cause strange errors
setsockopt(udp_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval));
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval));
do {
len = recv(udp_fd, ptr, to_recv - recvd, 0);
len = recv(sockfd, ptr, to_recv - recvd, 0);
if (len > 0) {
recvd += len;
ptr += len;
@ -308,36 +413,48 @@ static int run_stunclient(ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_a
} while (len < 0 && (errno == EINTR));
if (recvd > 0)
len = recvd;
buf.len = len;
len = recvd;
buf->len = len;
if (stun_is_command_message(&buf)) {
if (stun_is_command_message(buf)) {
if (stun_is_response(&buf)) {
if (stun_is_response(buf)) {
if (stun_is_success_response(&buf)) {
if (stun_is_success_response(buf)) {
if (stun_is_binding_response(&buf)) {
if (stun_is_binding_response(buf)) {
addr_set_any(reflexive_addr);
if (stun_attr_get_first_addr(&buf, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, reflexive_addr, NULL) >= 0) {
if (stun_attr_get_first_addr(buf, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, reflexive_addr, NULL) >= 0) {
stun_attr_ref sar = stun_attr_get_first_by_type_str(buf.buf, buf.len, STUN_ATTRIBUTE_OTHER_ADDRESS);
stun_attr_ref sar = stun_attr_get_first_by_type_str(buf->buf, buf->len, STUN_ATTRIBUTE_OTHER_ADDRESS);
if (sar) {
*rfc5780 = 1;
printf("\n========================================\n");
printf("RFC 5780 response %d\n",++counter);
stun_attr_get_addr_str((u08bits *) buf.buf, (size_t) buf.len, sar, other_addr, NULL);
sar = stun_attr_get_first_by_type_str(buf.buf, buf.len, STUN_ATTRIBUTE_RESPONSE_ORIGIN);
ioa_addr mapped_addr;
addr_set_any(&mapped_addr);
if (stun_attr_get_first_addr(buf, STUN_ATTRIBUTE_MAPPED_ADDRESS, &mapped_addr, NULL) >= 0) {
if (!addr_eq(&mapped_addr,reflexive_addr)){
printf("-= ALG detected! Mapped and XOR-Mapped differ! =-\n");
addr_debug_print(1, &mapped_addr, "Mapped Address: ");
}else {
printf("No ALG: Mapped == XOR-Mapped\n");
}
} else {
printf("Not received mapped address attribute.\n");
}
stun_attr_get_addr_str((u08bits *) buf->buf, (size_t) buf->len, sar, other_addr, NULL);
sar = stun_attr_get_first_by_type_str(buf->buf, buf->len, STUN_ATTRIBUTE_RESPONSE_ORIGIN);
if (sar) {
ioa_addr response_origin;
stun_attr_get_addr_str((u08bits *) buf.buf, (size_t) buf.len, sar, &response_origin, NULL);
stun_attr_get_addr_str((u08bits *) buf->buf, (size_t) buf->len, sar, &response_origin, NULL);
addr_debug_print(1, &response_origin, "Response origin: ");
}
addr_debug_print(1, other_addr, "Other addr: ");
}
addr_debug_print(1, reflexive_addr, "UDP reflexive addr");
addr_debug_print(1, local_addr, "Local addr: ");
} else {
printf("Cannot read the response\n");
}
@ -348,12 +465,14 @@ static int run_stunclient(ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_a
int err_code = 0;
u08bits err_msg[1025] = "\0";
size_t err_msg_size = sizeof(err_msg);
if (stun_is_error_response(&buf, &err_code, err_msg, err_msg_size)) {
if (stun_is_error_response(buf, &err_code, err_msg, err_msg_size)) {
printf("The response is an error %d (%s)\n", err_code, (char*) err_msg);
} else {
printf("The response is an unrecognized error\n");
}
}
} else if (stun_is_request(buf)) {
printf("Received a request (maybe a successful hairpinning)\n");
} else {
printf("The response is not a reponse message\n");
ret=1;
@ -368,38 +487,120 @@ static int run_stunclient(ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_a
}
}
socket_closesocket(udp_fd);
return ret;
}
static int run_stunclient(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, int *local_port, int *rfc5780, int change_ip, int change_port, int padding){
int ret=0;
stun_buffer buf;
init_socket(&udp_fd, local_addr, *local_port, remote_addr);
ret=stunclient_send(&buf, udp_fd, local_addr, local_port, remote_addr, change_ip, change_port, padding, -1);
ret=stunclient_receive(&buf, udp_fd, local_addr, reflexive_addr, other_addr, rfc5780);
socket_closesocket(udp_fd);
return ret;
}
static int run_stunclient_hairpinning(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, int *local_port, int *rfc5780, int change_ip, int change_port, int padding){
int ret=0;
stun_buffer buf;
stun_buffer buf2;
init_socket(&udp_fd, local_addr, *local_port, remote_addr);
ret=stunclient_send(&buf, udp_fd, local_addr, local_port, remote_addr, change_ip, change_port, padding, -1);
ret=stunclient_receive(&buf, udp_fd, local_addr, reflexive_addr, other_addr, rfc5780);
addr_cpy(remote_addr,reflexive_addr);
addr_set_port(local_addr, 0);
init_socket(&udp_fd2,local_addr,0,remote_addr);
ret=stunclient_send(&buf2, udp_fd2, local_addr, local_port, remote_addr, change_ip, change_port, padding, -1);
ret=stunclient_receive(&buf, udp_fd, local_addr, reflexive_addr, other_addr, rfc5780);
if(ret){
ret=stunclient_receive(&buf2, udp_fd2, local_addr, reflexive_addr, other_addr, rfc5780);
}
socket_closesocket(udp_fd);
socket_closesocket(udp_fd2);
return ret;
}
static int run_stunclient_lifetime(int timer,ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr, int *local_port, int *rfc5780, int change_ip, int change_port, int padding){
int ret=0;
stun_buffer buf;
stun_buffer buf2;
int response_port;
init_socket(&udp_fd, local_addr, *local_port, remote_addr);
ret=stunclient_send(&buf, udp_fd, local_addr, local_port, remote_addr, change_ip, change_port, padding, -1);
ret=stunclient_receive(&buf, udp_fd, local_addr, reflexive_addr, other_addr, rfc5780);
addr_set_port(local_addr, 0);
sleep(timer);
init_socket(&udp_fd2,local_addr,0,remote_addr);
response_port=addr_get_port(reflexive_addr);
ret=stunclient_send(&buf2, udp_fd2, local_addr, local_port, remote_addr, change_ip, change_port, padding, response_port);
ret=stunclient_receive(&buf, udp_fd, local_addr, reflexive_addr, other_addr, rfc5780);
socket_closesocket(udp_fd);
socket_closesocket(udp_fd2);
return ret;
}
#endif
//////////////// local definitions /////////////////
static char Usage[] =
"Usage: natdiscovery [options] address\n"
"Options:\n"
" -m NAT mapping behavior discovery\n"
" -f NAT filtering behavior discovery\n"
" -p STUN server port (Default: 3478)\n"
" -L Local address to use (optional)\n";
"Usage: natdiscovery [options] address\n"
"Options:\n"
" -m NAT mapping behavior discovery\n"
" -f NAT filtering behavior discovery\n"
" -t NAT mapping lifetime behavior discovery\n"
" Requires a timer (-T)\n"
" -c NAT collision behavior discovery\n"
" Requires an alternative IP address (-A)\n"
" -H NAT hairpinning behavior discovery\n"
" -P Add 1500 byte Padding to the behavior discovery\n"
" Applicable with all except NAT mapping Lifetime discovery\n"
" -p STUN server port (Default: 3478)\n"
" -L Local address to use (optional)\n"
" -l Local port to use (use with -L)\n"
" -A Local alrernative address to use\n"
" Used by collision behavior discovery\n"
" -T Mapping lifetime timer (sec)\n"
" Used by mapping lifetime behavior discovery\n";
//////////////////////////////////////////////////
static void init(ioa_addr *real_local_addr,ioa_addr *remote_addr,int *local_port,int port, int *rfc5780, char* local_addr, char* remote_param)
static void init(int first, ioa_addr *local_addr, ioa_addr *remote_addr, int *local_port, int port, int *rfc5780, char* local_addr_string, char* remote_param)
{
addr_set_any(real_local_addr);
addr_set_any(local_addr);
if(local_addr[0]) {
if(make_ioa_addr((const u08bits*)local_addr, 0, real_local_addr)<0) {
err(-1,NULL);
}
}
if(local_addr_string[0]) {
if(make_ioa_addr((const u08bits*)local_addr_string, 0, local_addr)<0) {
err(-1,NULL);
}
}
if (!first) *local_port=-1;
*rfc5780 = 0;
*local_port = -1;
*rfc5780 = 0;
if (make_ioa_addr((const u08bits*)remote_param, port, remote_addr) < 0)
err(-1, NULL);
if (make_ioa_addr((const u08bits*)remote_param, port, remote_addr) < 0)
err(-1, NULL);
}
static void discoveryresult(const char *decision){
@ -410,112 +611,201 @@ static void discoveryresult(const char *decision){
int main(int argc, char **argv)
{
int port = DEFAULT_STUN_PORT;
char local_addr[256]="\0";
int c=0;
int mapping = 0;
int filtering = 0;
int local_port, rfc5780;
ioa_addr other_addr, reflexive_addr, tmp_addr, remote_addr;
int remote_port = DEFAULT_STUN_PORT;
char local_addr_string[256]="\0";
char local2_addr_string[256]="\0";
int c=0;
int mapping = 0;
int filtering = 0;
int lifetime=0;
int timer=-1;
int collision = 0;
int padding = 0;
int hairpinning = 0;
int local_port=-1;
int rfc5780;
int first=1;
ioa_addr other_addr, reflexive_addr, tmp_addr, remote_addr, local_addr, local2_addr;
set_logfile("stdout");
set_system_parameters(0);
ns_bzero(local_addr, sizeof(local_addr));
addr_set_any(&remote_addr);
addr_set_any(&other_addr);
addr_set_any(&reflexive_addr);
addr_set_any(&tmp_addr);
while ((c = getopt(argc, argv, "mfp:L:")) != -1) {
switch(c) {
case 'm':
mapping=1;
break;
case 'f':
filtering=1;
break;
case 'p':
port = atoi(optarg);
break;
case 'L':
STRCPY(local_addr, optarg);
break;
default:
fprintf(stderr,"%s\n", Usage);
exit(1);
}
}
set_logfile("stdout");
set_system_parameters(0);
if(optind>=argc) {
fprintf(stderr, "%s\n", Usage);
exit(-1);
}
ns_bzero(local_addr_string, sizeof(local_addr_string));
ns_bzero(local2_addr_string, sizeof(local2_addr_string));
addr_set_any(&remote_addr);
addr_set_any(&other_addr);
addr_set_any(&reflexive_addr);
addr_set_any(&tmp_addr);
init(&real_local_addr, &remote_addr, &local_port, port, &rfc5780, local_addr, argv[optind]);
if (mapping) {
run_stunclient(&remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,-1,0,0,0);
if (addr_eq(&real_local_addr,&reflexive_addr)){
discoveryresult("No NAT! (Endpoint Independent Mapping)");
while ((c = getopt(argc, argv, "mftcPHp:L:l:A:T:")) != -1) {
switch(c) {
case 'm':
mapping=1;
break;
case 'f':
filtering=1;
break;
case 't':
lifetime=1;
break;
case 'c':
collision=1;
break;
case 'H':
hairpinning=1;
break;
case 'P':
padding=1;
break;
case 'p':
remote_port = atoi(optarg);
break;
case 'L':
STRCPY(local_addr_string, optarg);
break;
case 'l':
local_port = atoi(optarg);
break;
case 'A':
STRCPY(local2_addr_string, optarg);
break;
case 'T':
timer = atoi(optarg);
break;
default:
fprintf(stderr,"%s\n", Usage);
exit(1);
}
}
if(rfc5780) {
if(!addr_any(&other_addr)){
addr_cpy(&tmp_addr, &reflexive_addr);
addr_cpy(&remote_addr, &other_addr);
addr_set_port(&remote_addr, port);
if(optind>=argc) {
fprintf(stderr, "%s\n", Usage);
exit(-1);
}
run_stunclient(&remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,-1,0,0,0);
if(collision && !strcmp(local2_addr_string,"\0")){
fprintf(stderr, "Use \"-A\" to add an Alternative local IP address.\n");
fprintf(stderr, "It is mandatory with \"-c\" collision behavior detection..\n");
exit(-1);
}
if(addr_eq(&tmp_addr,&reflexive_addr)){
discoveryresult("NAT with Enpoint Independent Mapping!");
} else {
if(lifetime && timer==-1){
fprintf(stderr, "Use \"-T\" to add a timer value (in sec).\n");
fprintf(stderr, "It is mandatory with \"-b\" mapping lifetime behavior detection..\n");
exit(-1);
}
if(local_port>=0 && !strcmp(local_addr_string,"\0")){
fprintf(stderr, "To use local port please specify local address \"-L\"!\n");
fprintf(stderr, "We need to know the address familly to set the port.\n");
exit(-1);
}
if(lifetime) {
printf("\n-= Mapping Lifetime Behavior Discovery =-\n");
init(first, &local_addr, &remote_addr, &local_port, remote_port, &rfc5780, local_addr_string, argv[optind]);
first=0;
run_stunclient_lifetime(timer, &local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,0,0,padding);
}
if(hairpinning) {
printf("\n-= Hairpinning Behavior Discovery =-\n");
init(first, &local_addr, &remote_addr, &local_port, remote_port, &rfc5780, local_addr_string, argv[optind]);
first=0;
run_stunclient_hairpinning(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,0,0,padding);
}
if(mapping) {
printf("\n-= Mapping Behavior Discovery =-\n");
init(first,&local_addr, &remote_addr, &local_port, remote_port, &rfc5780, local_addr_string, argv[optind]);
first=0;
run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,0,0,padding);
if (addr_eq(&local_addr,&reflexive_addr)){
discoveryresult("No NAT! (Endpoint Independent Mapping)");
}
if(rfc5780) {
if(!addr_any(&other_addr)){
addr_cpy(&tmp_addr, &reflexive_addr);
addr_cpy(&remote_addr, &other_addr);
run_stunclient(&remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,-1,0,0,0);
addr_set_port(&remote_addr, remote_port);
run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,0,0,padding);
if(addr_eq(&tmp_addr,&reflexive_addr)){
discoveryresult("NAT with Address Dependent Mapping!");
discoveryresult("NAT with Enpoint Independent Mapping!");
} else {
discoveryresult("NAT with Address and Port Dependent Mapping!");
addr_cpy(&tmp_addr, &reflexive_addr);
addr_cpy(&remote_addr, &other_addr);
run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,0,0,padding);
if(addr_eq(&tmp_addr,&reflexive_addr)){
discoveryresult("NAT with Address Dependent Mapping!");
} else {
discoveryresult("NAT with Address and Port Dependent Mapping!");
}
}
};
}
}
}
init(&real_local_addr, &remote_addr, &local_port, port, &rfc5780, local_addr, argv[optind]);
if (filtering) {
run_stunclient(&remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,-1,0,0,0);
if (addr_eq(&real_local_addr,&reflexive_addr)){
discoveryresult("No NAT! (Endpoint Independent Mapping)");
}
}
}
if(rfc5780) {
if(!addr_any(&other_addr)){
int res=0;
res=run_stunclient(&remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,-1,1,1,0);
if (!res) {
discoveryresult("NAT with Enpoint Independent Filtering!");
} else {
res=0;
res=run_stunclient(&remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,-1,0,1,0);
if(!res){
discoveryresult("NAT with Address Dependent Filtering!");
if(filtering) {
printf("\n-= Filtering Behavior Discovery =-\n");
init(first,&local_addr, &remote_addr, &local_port, remote_port, &rfc5780, local_addr_string, argv[optind]);
first=0;
run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,0,0,padding);
if(addr_eq(&local_addr, &reflexive_addr)){
discoveryresult("No NAT! (Endpoint Independent Mapping)");
}
if(rfc5780) {
if(!addr_any(&other_addr)){
int res=0;
res=run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,1,1,padding);
if (!res) {
discoveryresult("NAT with Enpoint Independent Filtering!");
} else {
discoveryresult("NAT with Address and Port Dependent Filtering!");
res=0;
res=run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,0,1,padding);
if(!res){
discoveryresult("NAT with Address Dependent Filtering!");
} else {
discoveryresult("NAT with Address and Port Dependent Filtering!");
}
}
};
}
}
}
}
}
}
if (!filtering && !mapping) {
printf("Please use either -f or -m parameter for Filtering or Mapping behavior discovery.\n");
}
socket_closesocket(udp_fd);
return 0;
if(collision) {
printf("\n-= Collision Behavior Discovery =-\n");
init(first,&local_addr, &remote_addr, &local_port, remote_port, &rfc5780, local_addr_string, argv[optind]);
first=0;
addr_set_any(&local2_addr);
if(local2_addr_string[0]) {
if(make_ioa_addr((const u08bits*)local2_addr_string, 0, &local2_addr)<0) {
err(-1,NULL);
}
}
run_stunclient(&local_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,0,0,padding);
addr_set_port(&local2_addr,addr_get_port(&local_addr));
run_stunclient(&local2_addr, &remote_addr, &reflexive_addr, &other_addr, &local_port, &rfc5780,0,0,padding);
}
if (!filtering && !mapping && !collision && !hairpinning && !lifetime) {
printf("Please use either -f or -m or -c or -t or -H parameter for Filtering or Mapping behavior discovery.\n");
}
socket_closesocket(udp_fd);
socket_closesocket(udp_fd2);
return 0;
}

View File

@ -598,6 +598,7 @@ static char Usage[] = "Usage: turnserver [options]\n"
" After the initialization, the turnserver process\n"
" will make an attempt to change the current group ID to that group.\n"
" --mobility Mobility with ICE (MICE) specs support.\n"
" --no-http Turn OFF the HTTP-Admin-Interface. By default it is always ON.\n"
" --no-cli Turn OFF the CLI support. By default it is always ON.\n"
" --cli-ip=<IP> Local system IP address to be used for CLI server endpoint. Default value\n"
" is 127.0.0.1.\n"
@ -742,7 +743,8 @@ enum EXTRA_OPTS {
ADMIN_USER_QUOTA_OPT,
SERVER_NAME_OPT,
OAUTH_OPT,
PROD_OPT
PROD_OPT,
NO_HTTP_OPT
};
struct myoption {
@ -849,6 +851,7 @@ static const struct myoption long_options[] = {
{ "cli-ip", required_argument, NULL, CLI_IP_OPT },
{ "cli-port", required_argument, NULL, CLI_PORT_OPT },
{ "cli-password", required_argument, NULL, CLI_PASSWORD_OPT },
{ "no-http", optional_argument, NULL, NO_HTTP_OPT },
{ "server-relay", optional_argument, NULL, SERVER_RELAY_OPT },
{ "cli-max-output-sessions", required_argument, NULL, CLI_MAX_SESSIONS_OPT },
{ "ec-curve-name", required_argument, NULL, EC_CURVE_NAME_OPT },
@ -992,6 +995,9 @@ static void set_option(int c, char *value)
case NO_CLI_OPT:
use_cli = !get_bool_value(value);
break;
case NO_HTTP_OPT:
use_http = !get_bool_value(value);
break;
case CLI_IP_OPT:
if(make_ioa_addr((const u08bits*)value,0,&cli_addr)<0) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot set cli address: %s\n",value);

View File

@ -1651,7 +1651,7 @@ static void setup_relay_server(struct relay_server *rs, ioa_engine_handle e, int
send_turn_session_info,
send_https_socket,
allocate_bps,
turn_params.oauth, turn_params.oauth_server_name);
turn_params.oauth, turn_params.oauth_server_name, use_http);
if(to_set_rfc5780) {
set_rfc5780(&(rs->server), get_alt_addr, send_message_from_listener_to_client);

View File

@ -3596,6 +3596,14 @@ void turn_report_allocation_delete(void *a)
}
send_message_to_redis(e->rch, "del", key, "");
send_message_to_redis(e->rch, "publish", key, "deleted");
// report total traffic usage for this allocation
if(ss->realm_options.name[0]) {
snprintf(key, sizeof(key), "turn/realm/%s/user/%s/allocation/%018llu/total_traffic", ss->realm_options.name, (char*)ss->username, (unsigned long long)ss->id);
} else {
snprintf(key, sizeof(key), "turn/user/%s/allocation/%018llu/total_traffic", (char*)ss->username, (unsigned long long)ss->id);
}
send_message_to_redis(e->rch, "publish", key, "rcvp=%lu, rcvb=%lu, sentp=%lu, sentb=%lu", (unsigned long)(ss->t_received_packets), (unsigned long)(ss->t_received_bytes), (unsigned long)(ss->t_sent_packets), (unsigned long)(ss->t_sent_bytes));
}
#endif
}

View File

@ -77,6 +77,8 @@ struct admin_server adminserver;
int use_cli = 1;
int use_http = 1;
ioa_addr cli_addr;
int cli_addr_set = 0;
@ -1210,8 +1212,7 @@ void setup_admin_thread(void)
bufferevent_setcb(adminserver.in_buf, admin_server_receive_message, NULL, NULL, &adminserver);
bufferevent_enable(adminserver.in_buf, EV_READ);
}
{
if (use_http) {
struct bufferevent *pair[2];
bufferevent_pair_new(adminserver.event_base, TURN_BUFFEREVENTS_OPTIONS, pair);

View File

@ -81,6 +81,8 @@ extern struct admin_server adminserver;
extern int use_cli;
extern int use_http;
#define CLI_DEFAULT_IP ("127.0.0.1")
extern ioa_addr cli_addr;
extern int cli_addr_set;

View File

@ -31,7 +31,7 @@
#ifndef __IOADEFS__
#define __IOADEFS__
#define TURN_SERVER_VERSION "4.5.0.6"
#define TURN_SERVER_VERSION "4.5.0.7"
#define TURN_SERVER_VERSION_NAME "dan Eider"
#define TURN_SOFTWARE "Coturn-" TURN_SERVER_VERSION " '" TURN_SERVER_VERSION_NAME "'"

View File

@ -4543,32 +4543,34 @@ static int read_client_connection(turn_turnserver *server,
}
} else {
SOCKET_TYPE st = get_ioa_socket_type(ss->client_socket);
if(is_stream_socket(st)) {
if(is_http((char*)ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh))) {
const char *proto = "HTTP";
ioa_network_buffer_data(in_buffer->nbh)[ioa_network_buffer_get_size(in_buffer->nbh)] = 0;
if(st==TLS_SOCKET) {
proto = "HTTPS";
set_ioa_socket_app_type(ss->client_socket,HTTPS_CLIENT_SOCKET);
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s (%s %s) request: %s\n", __FUNCTION__, proto, get_ioa_socket_cipher(ss->client_socket), get_ioa_socket_ssl_method(ss->client_socket), (char*)ioa_network_buffer_data(in_buffer->nbh));
if(server->send_https_socket) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s socket to be detached: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)ss->client_socket, get_ioa_socket_type(ss->client_socket), get_ioa_socket_app_type(ss->client_socket));
ioa_socket_handle new_s = detach_ioa_socket(ss->client_socket);
if(new_s) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s new detached socket: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)new_s, get_ioa_socket_type(new_s), get_ioa_socket_app_type(new_s));
server->send_https_socket(new_s);
if (server->use_http) {
SOCKET_TYPE st = get_ioa_socket_type(ss->client_socket);
if(is_stream_socket(st)) {
if(is_http((char*)ioa_network_buffer_data(in_buffer->nbh), ioa_network_buffer_get_size(in_buffer->nbh))) {
const char *proto = "HTTP";
ioa_network_buffer_data(in_buffer->nbh)[ioa_network_buffer_get_size(in_buffer->nbh)] = 0;
if(st==TLS_SOCKET) {
proto = "HTTPS";
set_ioa_socket_app_type(ss->client_socket,HTTPS_CLIENT_SOCKET);
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s (%s %s) request: %s\n", __FUNCTION__, proto, get_ioa_socket_cipher(ss->client_socket), get_ioa_socket_ssl_method(ss->client_socket), (char*)ioa_network_buffer_data(in_buffer->nbh));
if(server->send_https_socket) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s socket to be detached: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)ss->client_socket, get_ioa_socket_type(ss->client_socket), get_ioa_socket_app_type(ss->client_socket));
ioa_socket_handle new_s = detach_ioa_socket(ss->client_socket);
if(new_s) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s new detached socket: 0x%lx, st=%d, sat=%d\n", __FUNCTION__,(long)new_s, get_ioa_socket_type(new_s), get_ioa_socket_app_type(new_s));
server->send_https_socket(new_s);
}
ss->to_be_closed = 1;
}
ss->to_be_closed = 1;
} else {
set_ioa_socket_app_type(ss->client_socket,HTTP_CLIENT_SOCKET);
if(server->verbose) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s request: %s\n", __FUNCTION__, proto, (char*)ioa_network_buffer_data(in_buffer->nbh));
}
handle_http_echo(ss->client_socket);
}
} else {
set_ioa_socket_app_type(ss->client_socket,HTTP_CLIENT_SOCKET);
if(server->verbose) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: %s request: %s\n", __FUNCTION__, proto, (char*)ioa_network_buffer_data(in_buffer->nbh));
}
handle_http_echo(ss->client_socket);
return 0;
}
return 0;
}
}
}
@ -4825,7 +4827,7 @@ void init_turn_server(turn_turnserver* server,
send_turn_session_info_cb send_turn_session_info,
send_https_socket_cb send_https_socket,
allocate_bps_cb allocate_bps_func,
int oauth, const char* oauth_server_name) {
int oauth, const char* oauth_server_name, int use_http) {
if (!server)
return;
@ -4892,6 +4894,8 @@ void init_turn_server(turn_turnserver* server,
server->allocate_bps_func = allocate_bps_func;
server->use_http = use_http;
set_ioa_timer(server->e, 1, 0, timer_timeout_handler, server, 1, "timer_timeout_handler");
}

View File

@ -169,6 +169,9 @@ struct _turn_turnserver {
/* oAuth: */
int oauth;
const char* oauth_server_name;
/* HTTP-Admin-Server: */
int use_http;
};
const char * get_version(turn_turnserver *server);
@ -212,7 +215,8 @@ void init_turn_server(turn_turnserver* server,
send_https_socket_cb send_https_socket,
allocate_bps_cb allocate_bps_func,
int oauth,
const char* oauth_server_name);
const char* oauth_server_name,
int use_http);
ioa_engine_handle turn_server_get_engine(turn_turnserver *s);

View File

@ -16,6 +16,12 @@ The keys are "turn/user/<username>/allocation/<id>/traffic". The application tha
in the traffic information must subscribe to the events as:
psubscribe turn/realm/*/user/*/allocation/*/traffic
Total traffic information is also reported when the allocation is deleted. The keys are
"turn/user/<username>/allocation/<id>/total_traffic". Applications interested in the total amount
of traffic per allocation can subscribe to these events as:
psubscribe turn/realm/*/user/*/allocation/*/total_traffic
Or, to receive all allocation events: