Ver código fonte

Merge branch 'master' into remove-trailing-spaces-from-READMEs

Mészáros Mihály 5 anos atrás
pai
commit
c8c6cdd226

+ 6 - 0
ChangeLog

@@ -51,6 +51,12 @@ Version 4.5.1.2 'dan Eider':
 	- merge PR #488 Fix typos about INSTALL filenames (by raccoonback)
 	- fix compiler warning comparison between signed and unsigned integer expressions
 	- fix compiler warning string truncation
+	- change Diffie Hellman default key length from 1066 to 2066
+	- merge PR #522 drop of supplementary group IDs (by weberhofer)
+	- merge PR #514 Unify spelling of Coturn (by paulmenzel)
+	- merge PR#506 Rename "prod" config option to "no-software-attribute" (by dbrgn)
+	- merge PR #519 fix config extension in README.docker (by ooookai)
+	- merge PR #516 change sql data dir in docker-compose-all.yml (by raghumuppa) 
 
 02/03/2019 Oleg Moskalenko <[email protected]> Mihály Mészáros <[email protected]>
 Version 4.5.1.1 'dan Eider':

+ 8 - 4
README.turnserver

@@ -158,7 +158,7 @@ Flags:
 
 -o, --daemon		Run server as daemon.
 
---prod       	 	Production mode: hide the software version.
+--no-software-attribute	Production mode: hide the software version.
 
 -f, --fingerprint	Use fingerprints in the TURN messages. If an incoming request
 			contains a fingerprint, then TURN server will always add
@@ -190,9 +190,9 @@ Flags:
 
 --oauth			Support oAuth authentication, as in the third-party STUN/TURN RFC 7635.
 
---dh566			Use 566 bits predefined DH TLS key. Default size of the key is 1066.
+--dh566			Use 566 bits predefined DH TLS key. Default size of the key is 2066.
 
---dh2066		Use 2066 bits predefined DH TLS key. Default size of the key is 1066.
+--dh1066		Use 1066 bits predefined DH TLS key. Default size of the key is 2066.
 
 --no-tlsv1		Do not allow TLSv1/DTLSv1 protocol.
 
@@ -322,6 +322,10 @@ Options with values:
 --alt-tls-listening-port	Alternative listening port for TLS and DTLS protocols.
 			Default (or zero) value means "TLS listening port plus one".
 
+--tcp-proxy-port	Support connections from TCP loadbalancer on this port. The loadbalancer
+			should use the binary proxy protocol.
+			(https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)
+				
 --aux-server		Auxiliary STUN/TURN server listening endpoint.
 			Aux servers have almost full TURN and STUN functionality.
 			The (minor) limitations are:
@@ -457,7 +461,7 @@ Options with values:
 			by this option.
 
 --dh-file		Use custom DH TLS key, stored in PEM format in the file.
-			Flags --dh566 and --dh2066 are ignored when the DH key is taken from a file.
+			Flags --dh566 and --dh1066 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

+ 1 - 1
docker/README.docker

@@ -1,6 +1,6 @@
 Before you begin
  * copy db schema run ./cp-schema.sh
- * edit turnserver/turnserver.cfg according your db selection (mysql or postgresql or redis or mongodb)
+ * edit turnserver/turnserver.conf according your db selection (mysql or postgresql or redis or mongodb)
 
 # start
 

+ 2 - 2
docker/coturn/Dockerfile

@@ -8,11 +8,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
 	apt-get update && \
 	apt-get install -y build-essential git debhelper dpkg-dev libssl-dev libevent-dev sqlite3 libsqlite3-dev postgresql-client libpq-dev default-mysql-client default-libmysqlclient-dev libhiredis-dev libmongoc-dev libbson-dev
 
-# Clone coTURN
+# Clone Coturn
 WORKDIR ${BUILD_PREFIX}
 RUN git clone https://github.com/coturn/coturn.git
 
-# Build coTURN
+# Build Coturn
 WORKDIR coturn
 RUN ./configure
 RUN make

+ 2 - 2
docker/coturn/turnserver.conf

@@ -582,7 +582,7 @@ syslog
 # Implementers SHOULD make usage of the SOFTWARE attribute a
 # configurable option (https://tools.ietf.org/html/rfc5389#section-16.1.2)
 #
-#prod
+#no-software-attribute
 
 # Option to suppress STUN functionality, only TURN requests will be processed.
 # Run as TURN server only, all STUN requests will be ignored.
@@ -640,7 +640,7 @@ no-loopback-peers
 # Allocate Address Family according
 # If enabled then TURN server allocates address family according  the TURN
 # Client <=> Server communication address family.
-# (By default coTURN works according RFC 6156.)
+# (By default Coturn works according RFC 6156.)
 # !!Warning: Enabling this option breaks RFC6156 section-4.2 (violates use default IPv4)!!
 #
 #keep-address-family

+ 3 - 3
docker/docker-compose-all.yml

@@ -7,7 +7,7 @@ services:
       context: ./mysql
     restart: unless-stopped
     volumes:
-      - mysql-data:/var/lib/mysql/data
+      - mysql-data:/var/lib/mysql
     env_file: 
       - mysql/mysql.env
     networks:
@@ -19,7 +19,7 @@ services:
       context: ./postgresql
     restart: unless-stopped
     volumes:
-      - postgresql-data:/var/lib/postgresql/data
+      - postgresql-data:/var/lib/postgresql
     env_file: 
       - postgresql/postgresql.env
     networks:
@@ -49,7 +49,7 @@ services:
       - backend
 
 
-# coTURN
+# Coturn
   coturn:
     build:
       context: ./coturn

+ 1 - 1
docker/docker-compose-mongodb.yml

@@ -13,7 +13,7 @@ services:
       - backend
 
 
-# coTURN
+# Coturn
   coturn:
     build:
       context: ./coturn

+ 1 - 1
docker/docker-compose-mysql.yml

@@ -14,7 +14,7 @@ services:
       - backend
 
 
-# coTURN
+# Coturn
   coturn:
     build:
       context: ./coturn

+ 1 - 1
docker/docker-compose-postgresql.yml

@@ -14,7 +14,7 @@ services:
       - backend
 
 
-# coTURN
+# Coturn
   coturn:
     build:
       context: ./coturn

+ 1 - 1
docker/docker-compose-redis.yml

@@ -14,7 +14,7 @@ services:
       - backend
 
 
-# coTURN
+# Coturn
   coturn:
     build:
       context: ./coturn

+ 1 - 1
examples/etc/coturn.service

@@ -1,5 +1,5 @@
 [Unit]
-Description=coTURN STUN/TURN Server
+Description=Coturn STUN/TURN Server
 Documentation=man:coturn(1) man:turnadmin(1) man:turnserver(1)
 After=network.target
 After=network-online.target

+ 10 - 2
examples/etc/turnserver.conf

@@ -44,6 +44,14 @@
 # Default (or zero) value means "TLS listening port plus one".
 #
 #alt-tls-listening-port=0
+
+# Some network setups will require using a TCP reverse proxy in front
+# of the STUN server. If the proxy port option is set a single listener
+# is started on the given port that accepts connections using the
+# haproxy proxy protocol v2.
+# (https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)
+#
+#tcp-proxy-port=5555
 	
 # Listener IP address of relay server. Multiple listeners can be specified.
 # If no IP(s) specified in the config file or in the command line options, 
@@ -566,7 +574,7 @@
 # Implementers SHOULD make usage of the SOFTWARE attribute a
 # configurable option (https://tools.ietf.org/html/rfc5389#section-16.1.2)
 #
-#prod
+#no-software-attribute
 
 # Option to suppress STUN functionality, only TURN requests will be processed.
 # Run as TURN server only, all STUN requests will be ignored.
@@ -631,7 +639,7 @@
 # Allocate Address Family according 
 # If enabled then TURN server allocates address family according  the TURN 
 # Client <=> Server communication address family.
-# (By default coTURN works according RFC 6156.)
+# (By default Coturn works according RFC 6156.)
 # !!Warning: Enabling this option breaks RFC6156 section-4.2 (violates use default IPv4)!!
 #
 #keep-address-family

+ 1 - 1
man/man1/turnadmin.1

@@ -1,5 +1,5 @@
 .\" Text automatically generated by txt2man
-.TH TURN 1 "12 February 2020" "" ""
+.TH TURN 1 "28 April 2020" "" ""
 .SH GENERAL INFORMATION
 
 \fIturnadmin\fP is a TURN administration tool. This tool can be used to manage 

+ 13 - 9
man/man1/turnserver.1

@@ -1,5 +1,5 @@
 .\" Text automatically generated by txt2man
-.TH TURN 1 "12 February 2020" "" ""
+.TH TURN 1 "28 April 2020" "" ""
 .SH GENERAL INFORMATION
 
 The \fBTURN Server\fP project contains the source code of a TURN server and TURN client 
@@ -234,10 +234,8 @@ Extra verbose mode, very annoying and not recommended.
 .B
 \fB\-o\fP, \fB\-\-daemon\fP
 Run server as daemon.
-.TP
-.B
-\fB\-\-prod\fP
-Production mode: hide the software version.
+.PP
+\fB\-\-no\-software\-attribute\fP Production mode: hide the software version.
 .TP
 .B
 \fB\-f\fP, \fB\-\-fingerprint\fP
@@ -281,11 +279,11 @@ Support oAuth authentication, as in the third\-party STUN/TURN RFC 7635.
 .TP
 .B
 \fB\-\-dh566\fP
-Use 566 bits predefined DH TLS key. Default size of the key is 1066.
+Use 566 bits predefined DH TLS key. Default size of the key is 2066.
 .TP
 .B
-\fB\-\-dh2066\fP
-Use 2066 bits predefined DH TLS key. Default size of the key is 1066.
+\fB\-\-dh1066\fP
+Use 1066 bits predefined DH TLS key. Default size of the key is 2066.
 .TP
 .B
 \fB\-\-no\-tlsv1\fP
@@ -483,6 +481,12 @@ Alternative listening port for TLS and DTLS protocols.
 Default (or zero) value means "TLS listening port plus one".
 .TP
 .B
+\fB\-\-tcp\-proxy\-port\fP
+Support connections from TCP loadbalancer on this port. The loadbalancer
+should use the binary proxy protocol.
+(https://www.haproxy.org/download/1.8/doc/proxy\-protocol.txt)
+.TP
+.B
 \fB\-\-aux\-server\fP
 Auxiliary STUN/TURN server listening endpoint.
 Aux servers have almost full TURN and STUN functionality.
@@ -667,7 +671,7 @@ by this option.
 .B
 \fB\-\-dh\-file\fP
 Use custom DH TLS key, stored in PEM format in the file.
-Flags \fB\-\-dh566\fP and \fB\-\-dh2066\fP are ignored when the DH key is taken from a file.
+Flags \fB\-\-dh566\fP and \fB\-\-dh1066\fP are ignored when the DH key is taken from a file.
 .TP
 .B
 \fB\-l\fP, \fB\-\-log\-file\fP

+ 1 - 1
man/man1/turnutils.1

@@ -1,5 +1,5 @@
 .\" Text automatically generated by txt2man
-.TH TURN 1 "12 February 2020" "" ""
+.TH TURN 1 "28 April 2020" "" ""
 .SH GENERAL INFORMATION
 
 A set of turnutils_* programs provides some utility functionality to be used

+ 1 - 0
src/apps/common/apputils.c

@@ -439,6 +439,7 @@ int set_raw_socket_tos(evutil_socket_t fd, int family, int tos)
 int is_stream_socket(int st) {
 	switch(st) {
 	case TCP_SOCKET:
+	case TCP_SOCKET_PROXY:
 	case TLS_SOCKET:
 	case TENTATIVE_TCP_SOCKET:
 	case SCTP_SOCKET:

+ 28 - 18
src/apps/relay/mainrelay.c

@@ -90,7 +90,7 @@ NULL,
 NULL,
 #endif
 
-DH_1066, "", "", "",
+DH_2066, "", "", "",
 "turn_server_cert.pem","turn_server_pkey.pem", "", "",
 0,0,0,
 #if !TLS_SUPPORTED
@@ -110,8 +110,8 @@ NULL, PTHREAD_MUTEX_INITIALIZER,
 //////////////// Common params ////////////////////
 TURN_VERBOSE_NONE,0,0,0,0,
 "/var/run/turnserver.pid",
-DEFAULT_STUN_PORT,DEFAULT_STUN_TLS_PORT,0,0,1,
-0,0,0,0,
+DEFAULT_STUN_PORT,DEFAULT_STUN_TLS_PORT,0,0,0,1,
+0,0,0,0,0,
 "",
 "",0,
 {
@@ -402,6 +402,8 @@ static char Usage[] = "Usage: turnserver [options]\n"
 "                                                or in old RFC 3489 sense, default is \"listening port plus one\").\n"
 " --alt-tls-listening-port	<port>		Alternative listening port for TLS and DTLS,\n"
 " 						the default is \"TLS/DTLS port plus one\".\n"
+" --tcp-proxy-port		<port>		Support connections from TCP loadbalancer on this port. The loadbalancer should\n"
+"						use the binary proxy protocol (https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt)\n"
 " -L, --listening-ip		<ip>		Listener IP address of relay server. Multiple listeners can be specified.\n"
 " --aux-server			<ip:port>	Auxiliary STUN/TURN server listening endpoint.\n"
 "						Auxiliary servers do not have alternative ports and\n"
@@ -448,7 +450,7 @@ static char Usage[] = "Usage: turnserver [options]\n"
 " -v, --verbose					'Moderate' verbose mode.\n"
 " -V, --Verbose					Extra verbose mode, very annoying (for debug purposes only).\n"
 " -o, --daemon					Start process as daemon (detach from current shell).\n"
-" --prod       	 				Production mode: hide the software version.\n"
+" --no-software-attribute	 		Production mode: hide the software version (formerly --prod).\n"
 " -f, --fingerprint				Use fingerprints in the TURN messages.\n"
 " -a, --lt-cred-mech				Use the long-term credential mechanism.\n"
 " -z, --no-auth					Do not use any credential mechanism, allow anonymous access.\n"
@@ -555,10 +557,10 @@ static char Usage[] = "Usage: turnserver [options]\n"
 "						if pre-OpenSSL 1.0.2 is used. With OpenSSL 1.0.2+,\n"
 "						an optimal curve will be automatically calculated, if not defined\n"
 "						by this option.\n"
-" --dh566					Use 566 bits predefined DH TLS key. Default size of the predefined key is 1066.\n"
-" --dh2066					Use 2066 bits predefined DH TLS key. Default size of the predefined key is 1066.\n"
+" --dh566					Use 566 bits predefined DH TLS key. Default size of the predefined key is 2066.\n"
+" --dh1066					Use 1066 bits predefined DH TLS key. Default size of the predefined key is 2066.\n"
 " --dh-file	<dh-file-name>			Use custom DH TLS key, stored in PEM format in the file.\n"
-"						Flags --dh566 and --dh2066 are ignored when the DH key is taken from a file.\n"
+"						Flags --dh566 and --dh1066 are ignored when the DH key is taken from a file.\n"
 " --no-tlsv1					Do not allow TLSv1/DTLSv1 protocol.\n"
 " --no-tlsv1_1					Do not allow TLSv1.1 protocol.\n"
 " --no-tlsv1_2					Do not allow TLSv1.2/DTLSv1.2 protocol.\n"
@@ -713,6 +715,7 @@ static char AdminUsage[] = "Usage: turnadmin [command] [options]\n"
 enum EXTRA_OPTS {
 	NO_UDP_OPT=256,
 	NO_TCP_OPT,
+	TCP_PROXY_PORT_OPT,
 	NO_TLS_OPT,
 	NO_DTLS_OPT,
 	NO_UDP_RELAY_OPT,
@@ -766,7 +769,7 @@ enum EXTRA_OPTS {
 	CLI_MAX_SESSIONS_OPT,
 	EC_CURVE_NAME_OPT,
 	DH566_OPT,
-	DH2066_OPT,
+	DH1066_OPT,
 	NE_TYPE_OPT,
 	NO_SSLV2_OPT, /*deprecated*/
 	NO_SSLV3_OPT, /*deprecated*/
@@ -779,7 +782,7 @@ enum EXTRA_OPTS {
 	ADMIN_USER_QUOTA_OPT,
 	SERVER_NAME_OPT,
 	OAUTH_OPT,
-	PROD_OPT,
+	NO_SOFTWARE_ATTRIBUTE_OPT,
 	NO_HTTP_OPT,
 	SECRET_KEY_OPT
 };
@@ -805,6 +808,7 @@ static const struct myoption long_options[] = {
 				{ "tls-listening-port", required_argument, NULL, TLS_PORT_OPT },
 				{ "alt-listening-port", required_argument, NULL, ALT_PORT_OPT },
 				{ "alt-tls-listening-port", required_argument, NULL, ALT_TLS_PORT_OPT },
+				{ "tcp-proxy-port", required_argument, NULL, TCP_PROXY_PORT_OPT },
 				{ "listening-ip", required_argument, NULL, 'L' },
 				{ "relay-device", required_argument, NULL, 'i' },
 				{ "relay-ip", required_argument, NULL, 'E' },
@@ -844,7 +848,8 @@ static const struct myoption long_options[] = {
 				{ "verbose", optional_argument, NULL, 'v' },
 				{ "Verbose", optional_argument, NULL, 'V' },
 				{ "daemon", optional_argument, NULL, 'o' },
-				{ "prod", optional_argument, NULL, PROD_OPT },
+/* deprecated: */		{ "prod", optional_argument, NULL, NO_SOFTWARE_ATTRIBUTE_OPT },
+				{ "no-software-attribute", optional_argument, NULL, NO_SOFTWARE_ATTRIBUTE_OPT },
 				{ "fingerprint", optional_argument, NULL, 'f' },
 				{ "check-origin-consistency", optional_argument, NULL, CHECK_ORIGIN_CONSISTENCY_OPT },
 				{ "no-udp", optional_argument, NULL, NO_UDP_OPT },
@@ -896,7 +901,7 @@ static const struct myoption long_options[] = {
 				{ "cli-max-output-sessions", required_argument, NULL, CLI_MAX_SESSIONS_OPT },
 				{ "ec-curve-name", required_argument, NULL, EC_CURVE_NAME_OPT },
 				{ "dh566", optional_argument, NULL, DH566_OPT },
-				{ "dh2066", optional_argument, NULL, DH2066_OPT },
+				{ "dh1066", optional_argument, NULL, DH1066_OPT },
 				{ "ne", required_argument, NULL, NE_TYPE_OPT },
 				{ "no-sslv2", optional_argument, NULL, NO_SSLV2_OPT }, /* deprecated */
 				{ "no-sslv3", optional_argument, NULL, NO_SSLV3_OPT }, /* deprecated */
@@ -1162,9 +1167,9 @@ static void set_option(int c, char *value)
 	  if(get_bool_value(value))
 		  turn_params.dh_key_size = DH_566;
 	  break;
-  case DH2066_OPT:
+  case DH1066_OPT:
 	  if(get_bool_value(value))
-		  turn_params.dh_key_size = DH_2066;
+		  turn_params.dh_key_size = DH_1066;
 	  break;
   case EC_CURVE_NAME_OPT:
 	  STRCPY(turn_params.ec_curve_name,value);
@@ -1266,6 +1271,10 @@ static void set_option(int c, char *value)
 	case ALT_TLS_PORT_OPT:
 		turn_params.alt_tls_listener_port = atoi(value);
 		break;
+	case TCP_PROXY_PORT_OPT:
+		turn_params.tcp_proxy_port = atoi(value);
+		turn_params.tcp_use_proxy = 1;
+		break;
 	case MIN_PORT_OPT:
 		turn_params.min_port = atoi(value);
 		break;
@@ -1378,8 +1387,8 @@ static void set_option(int c, char *value)
 			anon_credentials = 1;
 		}
 		break;
-	case PROD_OPT:
-		turn_params.prod = get_bool_value(value);
+	case NO_SOFTWARE_ATTRIBUTE_OPT:
+		turn_params.no_software_attribute = get_bool_value(value);
 		break;
 	case 'f':
 		turn_params.fingerprint = get_bool_value(value);
@@ -2061,6 +2070,7 @@ static void set_network_engine(void)
 
 static void drop_privileges(void)
 {
+	setgroups(0, NULL);
 	if(procgroupid_set) {
 		if(getgid() != procgroupid) {
 			if (setgid(procgroupid) != 0) {
@@ -2899,10 +2909,10 @@ static void set_ctx(SSL_CTX** out, const char *protocol, const SSL_METHOD* metho
 		if(!dh) {
 			if(turn_params.dh_key_size == DH_566)
 				dh = get_dh566();
-			else if(turn_params.dh_key_size == DH_2066)
-				dh = get_dh2066();
-			else
+			else if(turn_params.dh_key_size == DH_1066)
 				dh = get_dh1066();
+			else
+				dh = get_dh2066();
 		}
 
 		/*

+ 3 - 1
src/apps/relay/mainrelay.h

@@ -213,7 +213,7 @@ typedef struct _turn_params_ {
 
   int verbose;
   int turn_daemon;
-  int prod;
+  int no_software_attribute;
   int web_admin_listen_on_workers;
 
   int do_not_use_config_file;
@@ -226,10 +226,12 @@ typedef struct _turn_params_ {
   int tls_listener_port;
   int alt_listener_port;
   int alt_tls_listener_port;
+  int tcp_proxy_port;
   int rfc5780;
 
   int no_udp;
   int no_tcp;
+  int tcp_use_proxy;
   
   vint no_tcp_relay;
   vint no_udp_relay;

+ 5 - 5
src/apps/relay/netengine.c

@@ -1473,7 +1473,7 @@ static void setup_tcp_listener_servers(ioa_engine_handle e, struct relay_server
 	/* Create listeners */
 
 	/* Aux TCP servers */
-	if(!turn_params.no_tls || !turn_params.no_tcp) {
+	if(!turn_params.tcp_use_proxy && (!turn_params.no_tls || !turn_params.no_tcp)) {
 
 		for(i=0; i<turn_params.aux_servers_list.size; i++) {
 
@@ -1494,15 +1494,15 @@ static void setup_tcp_listener_servers(ioa_engine_handle e, struct relay_server
 
 		/* TCP: */
 		if(!turn_params.no_tcp) {
-			tcp_services[index] = create_tls_listener_server(turn_params.listener_ifname, turn_params.listener.addrs[i], turn_params.listener_port, turn_params.verbose, e, send_socket_to_general_relay, relay_server);
+			tcp_services[index] = create_tls_listener_server(turn_params.listener_ifname, turn_params.listener.addrs[i], turn_params.tcp_use_proxy?turn_params.tcp_proxy_port:turn_params.listener_port, turn_params.verbose, e, send_socket_to_general_relay, relay_server);
 			if(turn_params.rfc5780)
-				tcp_services[index+1] = create_tls_listener_server(turn_params.listener_ifname, turn_params.listener.addrs[i], get_alt_listener_port(), turn_params.verbose, e, send_socket_to_general_relay, relay_server);
+				tcp_services[index+1] = turn_params.tcp_use_proxy?NULL:create_tls_listener_server(turn_params.listener_ifname, turn_params.listener.addrs[i], get_alt_listener_port(), turn_params.verbose, e, send_socket_to_general_relay, relay_server);
 		} else {
 			tcp_services[index] = NULL;
 			if(turn_params.rfc5780)
 				tcp_services[index+1] = NULL;
 		}
-		if(!turn_params.no_tls && (turn_params.no_tcp || (turn_params.listener_port != turn_params.tls_listener_port))) {
+		if(!turn_params.no_tls && !turn_params.tcp_use_proxy && (turn_params.no_tcp || (turn_params.listener_port != turn_params.tls_listener_port))) {
 			tls_services[index] = create_tls_listener_server(turn_params.listener_ifname, turn_params.listener.addrs[i], turn_params.tls_listener_port, turn_params.verbose, e, send_socket_to_general_relay, relay_server);
 			if(turn_params.rfc5780)
 				tls_services[index+1] = create_tls_listener_server(turn_params.listener_ifname, turn_params.listener.addrs[i], get_alt_tls_listener_port(), turn_params.verbose, e, send_socket_to_general_relay, relay_server);
@@ -1651,7 +1651,7 @@ static void setup_relay_server(struct relay_server *rs, ioa_engine_handle e, int
 			 &turn_params.permission_lifetime,
 			 &turn_params.stun_only,
 			 &turn_params.no_stun,
-			 &turn_params.prod,
+			 &turn_params.no_software_attribute,
 			 &turn_params.web_admin_listen_on_workers,
 			 &turn_params.alternate_servers_list,
 			 &turn_params.tls_alternate_servers_list,

+ 100 - 20
src/apps/relay/ns_ioalib_engine_impl.c

@@ -2157,6 +2157,67 @@ static TURN_TLS_TYPE check_tentative_tls(ioa_socket_raw fd)
 }
 #endif
 
+static ssize_t socket_parse_proxy_v2(ioa_socket_handle s, uint8_t *buf, size_t len)
+{
+	if(len < 16){
+		return 0 ;
+	}
+
+	/* Check for proxy-v2 magic field */
+	char magic[] = {0x0D, 0x0A, 0x0D, 0x0A, 0x00, 0x0D, 0x0A, 0x51, 0x55, 0x49, 0x54, 0x0A};
+	if(memcmp(magic, buf, sizeof(magic))){
+		return -1;
+	}
+
+	/* Check version */
+	uint8_t version = buf[12] >> 4;
+	if(version != 2) return -1;
+
+	/* Read data */
+	uint8_t command = buf[12] & 0xF;
+	uint8_t family  = buf[13] >> 4;
+	uint8_t proto   = buf[13] & 0xF;
+	size_t plen   = ((size_t)buf[14] << 8) | buf[15];
+
+	size_t tlen = 16 + plen;
+	if(len < tlen) return 0;
+
+	/* A local connection is used by the proxy itself and does not carry a valid address */
+	if(command == 0) return tlen;
+
+	/* Accept only proxied TCP connections */
+	if(command != 1 || proto != 1) return -1;
+
+	/* Read the address */
+	if(family == 1 && plen >= 12){ /* IPv4 */
+		struct sockaddr_in remote, local;
+		remote.sin_family = local.sin_family = AF_INET;
+		memcpy(&remote.sin_addr.s_addr, &buf[16], 4);
+		memcpy(&local.sin_addr.s_addr,  &buf[20], 4);
+		memcpy(&remote.sin_port, &buf[24], 2);
+		memcpy(&local.sin_port,  &buf[26], 2);
+
+		addr_cpy4(&(s->local_addr),  &local);
+		addr_cpy4(&(s->remote_addr), &remote);
+
+	}else if(family == 2 && plen >= 36){ /* IPv6 */
+		struct sockaddr_in6 remote, local;
+		remote.sin6_family = local.sin6_family = AF_INET6;
+		memcpy(&remote.sin6_addr.s6_addr, &buf[16], 16);
+		memcpy(&local.sin6_addr.s6_addr,  &buf[32], 16);
+		memcpy(&remote.sin6_port, &buf[48], 2);
+		memcpy(&local.sin6_port,  &buf[50], 2);
+
+		addr_cpy6(&(s->local_addr),  &local);
+		addr_cpy6(&(s->remote_addr), &remote);
+
+        }else{
+		return -1;
+	}
+
+	return tlen;
+}
+
 static int socket_input_worker(ioa_socket_handle s)
 {
 	int len = 0;
@@ -2372,39 +2433,57 @@ static int socket_input_worker(ioa_socket_handle s)
 		struct evbuffer *inbuf = bufferevent_get_input(s->bev);
 		if(inbuf) {
 			ev_ssize_t blen = evbuffer_copyout(inbuf, buf_elem->buf.buf, STUN_BUFFER_SIZE);
+
 			if(blen>0) {
 				int mlen = 0;
 
 				if(blen>(ev_ssize_t)STUN_BUFFER_SIZE)
 				  blen=(ev_ssize_t)STUN_BUFFER_SIZE;
 
-				if(is_stream_socket(s->st) && ((s->sat == TCP_CLIENT_DATA_SOCKET)||(s->sat==TCP_RELAY_DATA_SOCKET))) {
-					mlen = blen;
-				} else {
-					mlen = stun_get_message_len_str(buf_elem->buf.buf, blen, 1, &app_msg_len);
-				}
-
-				if(mlen>0 && mlen<=(int)blen) {
-					len = (int)bufferevent_read(s->bev, buf_elem->buf.buf, mlen);
-					if(len < 0) {
-						ret = -1;
+				if(s->st == TCP_SOCKET_PROXY){
+					ssize_t tlen = socket_parse_proxy_v2(s, buf_elem->buf.buf, blen);
+					blen = 0;
+					if (tlen < 0){
 						s->tobeclosed = 1;
 						s->broken = 1;
-						log_socket_event(s, "socket read failed, to be closed",1);
-					} else if((s->st == TLS_SOCKET)||(s->st == TLS_SCTP_SOCKET)) {
-#if TLS_SUPPORTED
-						SSL *ctx = bufferevent_openssl_get_ssl(s->bev);
-						if(!ctx || SSL_get_shutdown(ctx)) {
+						ret = -1;
+						log_socket_event(s, "proxy protocol violated",1);
+					}else if(tlen > 0){
+						bufferevent_read(s->bev, buf_elem->buf.buf, tlen);
+
+						blen = evbuffer_copyout(inbuf, buf_elem->buf.buf, STUN_BUFFER_SIZE);
+						s->st = TCP_SOCKET;
+					}
+				}
+
+				if(blen){
+					if(is_stream_socket(s->st) && ((s->sat == TCP_CLIENT_DATA_SOCKET)||(s->sat==TCP_RELAY_DATA_SOCKET))) {
+						mlen = blen;
+					} else {
+						mlen = stun_get_message_len_str(buf_elem->buf.buf, blen, 1, &app_msg_len);
+					}
+
+					if(mlen>0 && mlen<=(int)blen) {
+						len = (int)bufferevent_read(s->bev, buf_elem->buf.buf, mlen);
+						if(len < 0) {
 							ret = -1;
 							s->tobeclosed = 1;
-						}
+							s->broken = 1;
+							log_socket_event(s, "socket read failed, to be closed",1);
+						} else if((s->st == TLS_SOCKET)||(s->st == TLS_SCTP_SOCKET)) {
+#if TLS_SUPPORTED
+							SSL *ctx = bufferevent_openssl_get_ssl(s->bev);
+							if(!ctx || SSL_get_shutdown(ctx)) {
+								ret = -1;
+								s->tobeclosed = 1;
+							}
 #endif
-					}
-					if(ret != -1) {
-						ret = len;
+						}
+						if(ret != -1) {
+							ret = len;
+						}
 					}
 				}
-
 			} else if(blen<0) {
 				s->tobeclosed = 1;
 				s->broken = 1;
@@ -3277,6 +3356,7 @@ int register_callback_on_ioa_socket(ioa_engine_handle e, ioa_socket_handle s, in
 					break;
 				case SCTP_SOCKET:
 				case TCP_SOCKET:
+				case TCP_SOCKET_PROXY:
 					if(s->bev) {
 						if(!clean_preexisting) {
 							TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,

+ 3 - 1
src/apps/relay/tls_listener.c

@@ -82,7 +82,9 @@ static void server_input_handler(struct evconnlistener *l, evutil_socket_t fd,
 
 	SOCKET_TYPE st = TENTATIVE_TCP_SOCKET;
 
-	if(turn_params.no_tls)
+	if(turn_params.tcp_use_proxy)
+		st = TCP_SOCKET_PROXY;
+	else if(turn_params.no_tls)
 		st = TCP_SOCKET;
 	else if(turn_params.no_tcp)
 		st = TLS_SOCKET;

+ 1 - 1
src/apps/relay/turn_admin_server.c

@@ -1659,7 +1659,7 @@ static void https_finish_page(struct str_buffer *sb, ioa_socket_handle s, int cc
 	str_buffer_append(sb,"</body>\r\n</html>\r\n");
 
 	send_str_from_ioa_socket_tcp(s,"HTTP/1.1 200 OK\r\nServer: ");
-	if(!turn_params.prod) {
+	if(!turn_params.no_software_attribute) {
 		send_str_from_ioa_socket_tcp(s,TURN_SOFTWARE);
 	}
 	send_str_from_ioa_socket_tcp(s,"\r\n");

+ 1 - 0
src/server/ns_turn_ioalib.h

@@ -90,6 +90,7 @@ enum _SOCKET_TYPE {
 	SCTP_SOCKET=132,
 	TLS_SCTP_SOCKET=133,
 	DTLS_SOCKET=250,
+	TCP_SOCKET_PROXY=253,
 	TENTATIVE_SCTP_SOCKET=254,
 	TENTATIVE_TCP_SOCKET=255
 };

+ 3 - 3
src/server/ns_turn_server.c

@@ -64,7 +64,7 @@ static inline int get_family(int stun_family, ioa_engine_handle e, ioa_socket_ha
 ////////////////////////////////////////////////
 
 const char * get_version(turn_turnserver *server) {
-	if(server && !*server->prod) {
+	if(server && !*server->no_software_attribute) {
 		return (const char *) TURN_SOFTWARE;
 	} else {
 		return (const char *) "None";
@@ -4900,7 +4900,7 @@ void init_turn_server(turn_turnserver* server,
 		vintp permission_lifetime,
 		vintp stun_only,
 		vintp no_stun,
-		vintp prod,
+		vintp no_software_attribute,
     vintp web_admin_listen_on_workers,
 		turn_server_addrs_list_t *alternate_servers_list,
 		turn_server_addrs_list_t *tls_alternate_servers_list,
@@ -4962,7 +4962,7 @@ void init_turn_server(turn_turnserver* server,
 	server->permission_lifetime = permission_lifetime;
 	server->stun_only = stun_only;
 	server->no_stun = no_stun;
-	server->prod = prod;
+	server->no_software_attribute = no_software_attribute;
 	server-> web_admin_listen_on_workers = web_admin_listen_on_workers;
 
 	server->dont_fragment = dont_fragment;

+ 2 - 2
src/server/ns_turn_server.h

@@ -120,7 +120,7 @@ struct _turn_turnserver {
         vintp permission_lifetime;
 	vintp stun_only;
 	vintp no_stun;
-	vintp prod;
+	vintp no_software_attribute;
 	vintp web_admin_listen_on_workers;
 	vintp secure_stun;
 	turn_credential_type ct;
@@ -199,7 +199,7 @@ void init_turn_server(turn_turnserver* server,
                                     vintp permission_lifetime,
 				    vintp stun_only,
 				    vintp no_stun,
-				    vintp prod,
+				    vintp no_software_attribute,
 				    vintp web_admin_listen_on_workers,
 				    turn_server_addrs_list_t *alternate_servers_list,
 				    turn_server_addrs_list_t *tls_alternate_servers_list,