diff --git a/ChangeLog b/ChangeLog index a5a43eb..6e6506d 100644 --- a/ChangeLog +++ b/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 Mihály Mészáros Version 4.5.1.1 'dan Eider': diff --git a/README.turnserver b/README.turnserver index 77304ab..07cd00f 100644 --- a/README.turnserver +++ b/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 diff --git a/docker/README.docker b/docker/README.docker index 0f88e58..3e7d6dc 100644 --- a/docker/README.docker +++ b/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 diff --git a/docker/coturn/Dockerfile b/docker/coturn/Dockerfile index 00722ee..b8fd207 100644 --- a/docker/coturn/Dockerfile +++ b/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 diff --git a/docker/coturn/turnserver.conf b/docker/coturn/turnserver.conf index d455dd3..ccc2750 100644 --- a/docker/coturn/turnserver.conf +++ b/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 diff --git a/docker/docker-compose-all.yml b/docker/docker-compose-all.yml index d3e06be..c20a53e 100644 --- a/docker/docker-compose-all.yml +++ b/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 diff --git a/docker/docker-compose-mongodb.yml b/docker/docker-compose-mongodb.yml index c4c675f..a163d23 100644 --- a/docker/docker-compose-mongodb.yml +++ b/docker/docker-compose-mongodb.yml @@ -13,7 +13,7 @@ services: - backend -# coTURN +# Coturn coturn: build: context: ./coturn diff --git a/docker/docker-compose-mysql.yml b/docker/docker-compose-mysql.yml index 2a68266..0600155 100644 --- a/docker/docker-compose-mysql.yml +++ b/docker/docker-compose-mysql.yml @@ -14,7 +14,7 @@ services: - backend -# coTURN +# Coturn coturn: build: context: ./coturn diff --git a/docker/docker-compose-postgresql.yml b/docker/docker-compose-postgresql.yml index 514a00e..b0376ce 100644 --- a/docker/docker-compose-postgresql.yml +++ b/docker/docker-compose-postgresql.yml @@ -14,7 +14,7 @@ services: - backend -# coTURN +# Coturn coturn: build: context: ./coturn diff --git a/docker/docker-compose-redis.yml b/docker/docker-compose-redis.yml index 4ae6f07..32d4109 100644 --- a/docker/docker-compose-redis.yml +++ b/docker/docker-compose-redis.yml @@ -14,7 +14,7 @@ services: - backend -# coTURN +# Coturn coturn: build: context: ./coturn diff --git a/examples/etc/coturn.service b/examples/etc/coturn.service index 45fb9a2..c3831f8 100644 --- a/examples/etc/coturn.service +++ b/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 diff --git a/examples/etc/turnserver.conf b/examples/etc/turnserver.conf index e917407..10e98ac 100644 --- a/examples/etc/turnserver.conf +++ b/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 diff --git a/man/man1/turnadmin.1 b/man/man1/turnadmin.1 index 92b1662..6373ea0 100644 --- a/man/man1/turnadmin.1 +++ b/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 diff --git a/man/man1/turnserver.1 b/man/man1/turnserver.1 index 6c7e96a..0ddd73b 100644 --- a/man/man1/turnserver.1 +++ b/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 diff --git a/man/man1/turnutils.1 b/man/man1/turnutils.1 index 7da6552..fbe7cff 100644 --- a/man/man1/turnutils.1 +++ b/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 diff --git a/src/apps/common/apputils.c b/src/apps/common/apputils.c index 57ee9e0..5e71176 100644 --- a/src/apps/common/apputils.c +++ b/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: diff --git a/src/apps/relay/mainrelay.c b/src/apps/relay/mainrelay.c index 6710da6..5fc77a4 100644 --- a/src/apps/relay/mainrelay.c +++ b/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 Alternative listening port for TLS and DTLS,\n" " the default is \"TLS/DTLS port plus one\".\n" +" --tcp-proxy-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 Listener IP address of relay server. Multiple listeners can be specified.\n" " --aux-server 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 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(); } /* diff --git a/src/apps/relay/mainrelay.h b/src/apps/relay/mainrelay.h index ea13984..c3a25b6 100644 --- a/src/apps/relay/mainrelay.h +++ b/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; diff --git a/src/apps/relay/netengine.c b/src/apps/relay/netengine.c index 1a69dcd..db2ebd2 100644 --- a/src/apps/relay/netengine.c +++ b/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> 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; - s->tobeclosed = 1; - } -#endif - } - if(ret != -1) { - ret = len; + 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; + } + } + } } 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, diff --git a/src/apps/relay/tls_listener.c b/src/apps/relay/tls_listener.c index a75c187..689c2f6 100644 --- a/src/apps/relay/tls_listener.c +++ b/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; diff --git a/src/apps/relay/turn_admin_server.c b/src/apps/relay/turn_admin_server.c index dade161..7ad2ab1 100644 --- a/src/apps/relay/turn_admin_server.c +++ b/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,"\r\n\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"); diff --git a/src/server/ns_turn_ioalib.h b/src/server/ns_turn_ioalib.h index 074e618..6737711 100644 --- a/src/server/ns_turn_ioalib.h +++ b/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 }; diff --git a/src/server/ns_turn_server.c b/src/server/ns_turn_server.c index 16a6511..38a1513 100644 --- a/src/server/ns_turn_server.c +++ b/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; diff --git a/src/server/ns_turn_server.h b/src/server/ns_turn_server.h index 628457f..924a507 100644 --- a/src/server/ns_turn_server.h +++ b/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,