native SCTP support

libevent.rpm
mom040267 10 years ago
parent 3888a928bf
commit 69653ea259
  1. 4
      ChangeLog
  2. 13
      INSTALL
  3. 7
      README.turnutils
  4. 13
      configure
  5. 2
      man/man1/turnadmin.1
  6. 2
      man/man1/turnserver.1
  7. 11
      man/man1/turnutils.1
  8. 2
      rpm/build.settings.sh
  9. 4
      rpm/turnserver.spec
  10. 12
      src/apps/relay/dtls_listener.c
  11. 8
      src/apps/relay/mainrelay.c
  12. 16
      src/apps/relay/netengine.c
  13. 24
      src/apps/relay/ns_ioalib_engine_impl.c
  14. 85
      src/apps/relay/tls_listener.c
  15. 10
      src/apps/uclient/mainuclient.c
  16. 4
      src/apps/uclient/startuclient.c
  17. 1
      src/apps/uclient/uclient.h
  18. 13
      src/ns_turn_defs.h

@ -1,6 +1,6 @@
3/15/2015 Oleg Moskalenko <mom040267@gmail.com>
Version 4.4.3.1 'Ardee West':
- SCTP support compilation option;
Version 4.4.4.1 'Ardee West':
- 'native' SCTP support;
2/28/2015 Oleg Moskalenko <mom040267@gmail.com>
Version 4.4.2.3 'Ardee West':

@ -1194,16 +1194,9 @@ newer has to be used. See OPENSSL section for the OpenSSL upgrade hints.
XXV. SCTP support
Starting with version 4.4.3.1, the TURN server can have 'native' SCTP support
compiling in (if the platform supports SCTP). If compiled with TURN_SCTP
environment variable set to a non-empty value, then SCTP replaces TCP in the
TURN client - TURN server communications:
$ TURN_SCTP=1 ./configure
$ make
With this option, on the client side, the TURN server will support UDP, DTLS,
SCTP and TLS-over-SCTP.
Starting with version 4.4.3.1, the TURN server supports 'native' SCTP.
On the client side, the TURN server, additionally, supports SCTP and
TLS-over-SCTP.
The relay side is not changing - the relay communications will still be UDP
or TCP.

@ -56,12 +56,15 @@ 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,
and ignores flags and options -s, -e, -r and -g.
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.
-S Secure SSL connection: SSL/TLS for TCP, DTLS for UDP, TLS/SCTP for SCTP.
-U Secure unencrypted connection (suite eNULL): SSL/TLS for TCP, DTLS for UDP.

13
configure vendored

@ -1157,22 +1157,11 @@ if [ -z "${LDCONFIG}" ] ; then
fi
fi
###############################
# SCTP
###############################
if [ -z "${TURN_SCTP}" ] ; then
echo "no SCTP support"
else
echo "compiling with native SCTP client-side support (in place of TCP)"
TURN_SCTP="-DTURN_SCTP"
fi
###############################
# So, what we have now:
###############################
OSCFLAGS="${OSCFLAGS} ${TURN_SCTP} ${TURN_NO_THREAD_BARRIERS} ${TURN_NO_DTLS} ${TURN_NO_GCM} ${TURN_NO_TLS} -DINSTALL_PREFIX=${PREFIX} -DTURNDB=${TURNDBDIR}/turndb"
OSCFLAGS="${OSCFLAGS} ${TURN_NO_THREAD_BARRIERS} ${TURN_NO_DTLS} ${TURN_NO_GCM} ${TURN_NO_TLS} -DINSTALL_PREFIX=${PREFIX} -DTURNDB=${TURNDBDIR}/turndb"
if ! [ -z "${TURN_ACCEPT_RPATH}" ] ; then
if [ -z "${TURN_DISABLE_RPATH}" ] ; then

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

@ -1,5 +1,5 @@
.\" Text automatically generated by txt2man
.TH TURN 1 "18 February 2015" "" ""
.TH TURN 1 "15 March 2015" "" ""
.SH GENERAL INFORMATION
The \fBTURN Server\fP project contains the source code of a TURN server and TURN client

@ -1,5 +1,5 @@
.\" Text automatically generated by txt2man
.TH TURN 1 "18 February 2015" "" ""
.TH TURN 1 "15 March 2015" "" ""
.SH GENERAL INFORMATION
A set of turnutils_* programs provides some utility functionality to be used
@ -70,9 +70,14 @@ Flags:
Use TCP for communications between client and TURN server (default is UDP).
.TP
.B
\fB\-b\fP
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.
and ignores flags and options \fB\-s\fP, \fB\-e\fP, \fB\-r\fP and \fB\-g\fP. Can be used together
with \fB\-b\fP.
.TP
.B
\fB\-P\fP
@ -80,7 +85,7 @@ Passive TCP (RFC6062 with active peer). Implies \fB\-T\fP.
.TP
.B
\fB\-S\fP
Secure SSL connection: SSL/TLS for TCP, DTLS for UDP.
Secure SSL connection: SSL/TLS for TCP, DTLS for UDP, TLS/SCTP for SCTP.
.TP
.B
\fB\-U\fP

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

@ -1,5 +1,5 @@
Name: turnserver
Version: 4.4.3.1
Version: 4.4.4.1
Release: 0%{dist}
Summary: Coturn TURN Server
@ -289,7 +289,7 @@ fi
%changelog
* Sun Mar 15 2015 Oleg Moskalenko <mom040267@gmail.com>
- Sync to 4.4.3.1
- Sync to 4.4.4.1
* Sat Feb 28 2015 Oleg Moskalenko <mom040267@gmail.com>
- Sync to 4.4.2.3
* Wed Feb 18 2015 Oleg Moskalenko <mom040267@gmail.com>

@ -777,13 +777,13 @@ static int create_server_socket(dtls_listener_relay_server_type* server, int rep
perror("Cannot bind local socket to addr");
char saddr[129];
addr_to_string(&server->addr,(u08bits*)saddr);
TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING,"Cannot bind UDP/DTLS listener socket to addr %s\n",saddr);
TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING,"Cannot bind DTLS/UDP listener socket to addr %s\n",saddr);
if(addr_bind_cycle++<max_binding_time) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Trying to bind UDP/DTLS listener socket to addr %s, again...\n",saddr);
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Trying to bind DTLS/UDP listener socket to addr %s, again...\n",saddr);
sleep(1);
goto retry_addr_bind;
}
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Fatal final failure: cannot bind UDP/DTLS listener socket to addr %s\n",saddr);
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Fatal final failure: cannot bind DTLS/UDP listener socket to addr %s\n",saddr);
exit(-1);
}
}
@ -797,7 +797,7 @@ static int create_server_socket(dtls_listener_relay_server_type* server, int rep
if(report_creation) {
if(!turn_params.no_udp && !turn_params.no_dtls)
addr_debug_print(server->verbose, &server->addr,"UDP/DTLS listener opened on");
addr_debug_print(server->verbose, &server->addr,"DTLS/UDP listener opened on");
else if(!turn_params.no_dtls)
addr_debug_print(server->verbose, &server->addr,"DTLS listener opened on");
else if(!turn_params.no_udp)
@ -868,7 +868,7 @@ static int reopen_server_socket(dtls_listener_relay_server_type* server, evutil_
if (!turn_params.no_udp && !turn_params.no_dtls)
addr_debug_print(server->verbose, &server->addr,
"UDP/DTLS listener opened on ");
"DTLS/UDP listener opened on ");
else if (!turn_params.no_dtls)
addr_debug_print(server->verbose, &server->addr,
"DTLS listener opened on ");
@ -920,7 +920,7 @@ static int init_server(dtls_listener_relay_server_type* server,
if(ifname) STRCPY(server->ifname,ifname);
if(make_ioa_addr((const u08bits*)local_address, port, &server->addr)<0) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot create a UDP/DTLS listener for address: %s\n",local_address);
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot create a DTLS/UDP listener for address: %s\n",local_address);
return -1;
}

@ -1614,7 +1614,7 @@ static void print_features(unsigned long mfn)
{
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\nRFC 3489/5389/5766/5780/6062/6156 STUN/TURN Server\nVersion %s\n",TURN_SOFTWARE);
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\nMax number of open files/sockets allowed for this process: %lu\n",mfn);
if(turn_params.net_engine_version == 1)
if(turn_params.net_engine_version == NEV_UDP_SOCKET_PER_ENDPOINT)
mfn = mfn/3;
else
mfn = mfn/2;
@ -1690,11 +1690,7 @@ static void set_network_engine(void)
turn_params.net_engine_version = NEV_UDP_SOCKET_PER_ENDPOINT;
#if defined(SO_REUSEPORT)
#if defined(__linux__) || defined(__LINUX__) || defined(__linux) || defined(linux__) || defined(LINUX) || defined(__LINUX) || defined(LINUX__)
if(CLIENT_STREAM_SOCKET_PROTOCOL == IPPROTO_IP) {
turn_params.net_engine_version = NEV_UDP_SOCKET_PER_THREAD;
} else {
turn_params.net_engine_version = NEV_UDP_SOCKET_PER_SESSION;
}
turn_params.net_engine_version = NEV_UDP_SOCKET_PER_THREAD;
#else /* BSD ? */
turn_params.net_engine_version = NEV_UDP_SOCKET_PER_SESSION;
#endif /* Linux */

@ -1842,16 +1842,20 @@ void setup_server(void)
if(udp_relay_servers[0]) {
tot = get_real_udp_relay_servers_number();
}
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Total UDP servers: %d\n",(int)tot);
if(tot) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Total UDP servers: %d\n",(int)tot);
}
}
{
int tot = get_real_general_relay_servers_number();
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Total General servers: %d\n",(int)tot);
int i;
for(i = 0;i<tot;i++) {
if(!(general_relay_servers[i])) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"General server %d is not initialized !\n",(int)i);
if(tot) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Total General servers: %d\n",(int)tot);
int i;
for(i = 0;i<tot;i++) {
if(!(general_relay_servers[i])) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"General server %d is not initialized !\n",(int)i);
}
}
}
}

@ -859,16 +859,12 @@ int set_socket_options_fd(evutil_socket_t fd, int tcp, int family)
} else {
if(CLIENT_STREAM_SOCKET_PROTOCOL == IPPROTO_IP) {
int flag = 1;
int result = setsockopt(fd, /* socket affected */
IPPROTO_TCP, /* set option at TCP level */
TCP_NODELAY, /* name of option */
(char*)&flag, /* value */
sizeof(int)); /* length of option value */
if (result < 0)
perror("TCP_NODELAY");
}
int flag = 1;
setsockopt(fd, /* socket affected */
IPPROTO_TCP, /* set option at TCP level */
TCP_NODELAY, /* name of option */
(char*)&flag, /* value */
sizeof(int)); /* length of option value */
socket_tcp_set_keepalive(fd);
}
@ -2714,7 +2710,7 @@ static void eventcb_bev(struct bufferevent *bev, short events, void *arg)
addr_to_string(&(s->remote_addr),(u08bits*)sraddr);
if (events & BEV_EVENT_EOF) {
if(server->verbose)
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"session %018llu: TCP socket closed remotely %s\n",(unsigned long long)(ss->id),sraddr);
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"session %018llu: TCP (or SCTP) socket closed remotely %s\n",(unsigned long long)(ss->id),sraddr);
if(s == ss->client_socket) {
shutdown_client_connection(server, ss, 0, "TCP connection closed by client (callback)");
} else if(s == ss->alloc.relay_sessions[ALLOC_IPV4_INDEX].s) {
@ -2726,12 +2722,12 @@ static void eventcb_bev(struct bufferevent *bev, short events, void *arg)
}
} else if (events & BEV_EVENT_ERROR) {
if(EVUTIL_SOCKET_ERROR()) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"session %018llu: TCP socket error: %s %s\n",(unsigned long long)(ss->id),
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"session %018llu: TCP (or SCTP) socket error: %s %s\n",(unsigned long long)(ss->id),
evutil_socket_error_to_string(EVUTIL_SOCKET_ERROR()), sraddr);
} else if(server->verbose) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"session %018llu: TCP socket disconnected: %s\n",(unsigned long long)(ss->id),sraddr);
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"session %018llu: TCP (or SCTP) socket disconnected: %s\n",(unsigned long long)(ss->id),sraddr);
}
shutdown_client_connection(server, ss, 0, "TCP socket buffer operation error (callback)");
shutdown_client_connection(server, ss, 0, "TCP (or SCTP) socket buffer operation error (callback)");
}
}
}

@ -38,6 +38,8 @@
#include <event2/listener.h>
#include <netinet/sctp.h>
///////////////////////////////////////////////////
#define FUNCSTART if(server && eve(server->verbose)) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"%s:%d:start\n",__FUNCTION__,__LINE__)
@ -50,6 +52,7 @@ struct tls_listener_relay_server_info
ioa_engine_handle e;
int verbose;
struct evconnlistener *l;
struct evconnlistener *sctp_l;
struct message_to_relay sm;
ioa_engine_new_connection_event_handler connect_cb;
struct relay_server *relay_server;
@ -149,13 +152,13 @@ static int create_server_listener(tls_listener_relay_server_type* server) {
perror("Cannot bind local socket to addr");
char saddr[129];
addr_to_string(&server->addr,(u08bits*)saddr);
TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING,"Cannot bind TCP/TLS listener socket to addr %s\n",saddr);
TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING,"Cannot bind TLS/TCP listener socket to addr %s\n",saddr);
if(addr_bind_cycle++<max_binding_time) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Trying to bind TCP/TLS listener socket to addr %s, again...\n",saddr);
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Trying to bind TLS/TCP listener socket to addr %s, again...\n",saddr);
sleep(1);
goto retry_addr_bind;
}
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Fatal final failure: cannot bind TCP/TLS listener socket to addr %s\n",saddr);
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Fatal final failure: cannot bind TLS/TCP listener socket to addr %s\n",saddr);
exit(-1);
}
}
@ -176,7 +179,7 @@ static int create_server_listener(tls_listener_relay_server_type* server) {
}
if(!turn_params.no_tcp && !turn_params.no_tls)
addr_debug_print(server->verbose, &server->addr,"TCP/TLS listener opened on ");
addr_debug_print(server->verbose, &server->addr,"TLS/TCP listener opened on ");
else if(!turn_params.no_tls)
addr_debug_print(server->verbose, &server->addr,"TLS listener opened on ");
else if(!turn_params.no_tcp)
@ -187,6 +190,78 @@ static int create_server_listener(tls_listener_relay_server_type* server) {
return 0;
}
static int sctp_create_server_listener(tls_listener_relay_server_type* server) {
FUNCSTART;
if(!server) return -1;
evutil_socket_t tls_listen_fd = -1;
tls_listen_fd = socket(server->addr.ss.sa_family, SCTP_CLIENT_STREAM_SOCKET_TYPE, SCTP_CLIENT_STREAM_SOCKET_PROTOCOL);
if (tls_listen_fd < 0) {
perror("socket");
return -1;
}
if(sock_bind_to_device(tls_listen_fd, (unsigned char*)server->ifname)<0) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot bind listener socket to device %s\n",server->ifname);
}
if(addr_bind(tls_listen_fd,&server->addr,1)<0) {
close(tls_listen_fd);
return -1;
}
socket_tcp_set_keepalive(tls_listen_fd);
socket_set_nonblocking(tls_listen_fd);
{
struct sctp_paddrparams heartbeat;
ns_bzero(&heartbeat, sizeof(struct sctp_paddrparams));
heartbeat.spp_flags = SPP_HB_ENABLE;
heartbeat.spp_hbinterval = 5000;
heartbeat.spp_pathmaxrxt = 5;
/*Set Heartbeats*/
if(setsockopt(tls_listen_fd, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS , &heartbeat, sizeof(heartbeat)) != 0)
perror("setsockopt");
}
{
struct sctp_rtoinfo rtoinfo;
ns_bzero(&rtoinfo, sizeof(struct sctp_rtoinfo));
rtoinfo.srto_max = 5000;
/*Set rto_max*/
if(setsockopt(tls_listen_fd, IPPROTO_SCTP, SCTP_RTOINFO , &rtoinfo, sizeof(rtoinfo)) != 0)
perror("setsockopt");
}
server->sctp_l = evconnlistener_new(server->e->event_base,
server_input_handler, server,
LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE,
1024, tls_listen_fd);
if(!(server->sctp_l)) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Cannot create SCTP listener\n");
socket_closesocket(tls_listen_fd);
return -1;
}
if (!turn_params.no_tls)
addr_debug_print(server->verbose, &server->addr, "TLS/SCTP listener opened on ");
else
addr_debug_print(server->verbose, &server->addr, "SCTP listener opened on ");
FUNCEND;
return 0;
}
static int init_server(tls_listener_relay_server_type* server,
const char* ifname,
const char *local_address,
@ -212,6 +287,8 @@ static int init_server(tls_listener_relay_server_type* server,
server->e = e;
sctp_create_server_listener(server);
return create_server_listener(server);
}

@ -55,6 +55,7 @@ int do_not_use_channel=0;
int c2c=0;
int clnet_verbose=TURN_VERBOSE_NONE;
int use_tcp=0;
int use_sctp=0;
int use_secure=0;
int hang_on=0;
ioa_addr peer_addr;
@ -112,8 +113,9 @@ static char Usage[] =
"Usage: uclient [flags] [options] turn-server-ip-address\n"
"Flags:\n"
" -t TCP (default - UDP).\n"
" -b SCTP (default - UDP).\n"
" -T TCP relay transport (default - UDP). Implies options -t, -y, -c, and ignores \n"
" options -s, -e, -r and -g.\n"
" options -s, -e, -r and -g. Can be used together with -b\n"
" -P Passive TCP (RFC6062 with active peer). Implies -T.\n"
" -S Secure connection: TLS for TCP, DTLS for UDP.\n"
" -U Secure connection with eNULL cipher.\n"
@ -218,7 +220,7 @@ int main(int argc, char **argv)
ns_bzero(local_addr, sizeof(local_addr));
while ((c = getopt(argc, argv, "a:d:p:l:n:L:m:e:r:u:w:i:k:z:W:C:E:F:o:ZvsyhcxXgtTSAPDNOUHYKMRIGBJ")) != -1) {
while ((c = getopt(argc, argv, "a:d:p:l:n:L:m:e:r:u:w:i:k:z:W:C:E:F:o:bZvsyhcxXgtTSAPDNOUHYKMRIGBJ")) != -1) {
switch (c){
case 'J': {
@ -366,6 +368,10 @@ int main(int argc, char **argv)
case 't':
use_tcp = 1;
break;
case 'b':
use_sctp = 1;
use_tcp = 1;
break;
case 'P':
passive_tcp = 1;
/* implies 'T': */

@ -230,8 +230,8 @@ static int clnet_connect(uint16_t clnet_remote_port, const char *remote_address,
ns_bzero(&local_addr, sizeof(ioa_addr));
clnet_fd = socket(remote_addr.ss.sa_family,
use_tcp ? CLIENT_STREAM_SOCKET_TYPE : CLIENT_DGRAM_SOCKET_TYPE,
use_tcp ? CLIENT_STREAM_SOCKET_PROTOCOL : CLIENT_DGRAM_SOCKET_PROTOCOL);
use_sctp ? SCTP_CLIENT_STREAM_SOCKET_TYPE : (use_tcp ? CLIENT_STREAM_SOCKET_TYPE : CLIENT_DGRAM_SOCKET_TYPE),
use_sctp ? SCTP_CLIENT_STREAM_SOCKET_PROTOCOL : (use_tcp ? CLIENT_STREAM_SOCKET_PROTOCOL : CLIENT_DGRAM_SOCKET_PROTOCOL));
if (clnet_fd < 0) {
perror("socket");
exit(-1);

@ -52,6 +52,7 @@ extern int clmessage_length;
extern int do_not_use_channel;
extern int clnet_verbose;
extern int use_tcp;
extern int use_sctp;
extern int use_secure;
extern char cert_file[1025];
extern char pkey_file[1025];

@ -31,7 +31,7 @@
#ifndef __IOADEFS__
#define __IOADEFS__
#define TURN_SERVER_VERSION "4.4.3.1"
#define TURN_SERVER_VERSION "4.4.4.1"
#define TURN_SERVER_VERSION_NAME "Ardee West"
#define TURN_SOFTWARE "Coturn-" TURN_SERVER_VERSION " '" TURN_SERVER_VERSION_NAME "'"
@ -218,19 +218,14 @@ typedef u32bits turn_time_t;
////////////////////////////////////////////////////////
//#define DGRAM_SOCKET_TYPE SOCK_SEQPACKET
//#define DGRAM_SOCKET_PROTOCOL IPPROTO_SCTP
#define CLIENT_DGRAM_SOCKET_TYPE SOCK_DGRAM
#define CLIENT_DGRAM_SOCKET_PROTOCOL IPPROTO_IP
#define CLIENT_STREAM_SOCKET_TYPE SOCK_STREAM
#define CLIENT_STREAM_SOCKET_PROTOCOL IPPROTO_IP
#if defined(TURN_SCTP)
#define CLIENT_STREAM_SOCKET_PROTOCOL IPPROTO_SCTP
#else
#define CLIENT_STREAM_SOCKET_PROTOCOL IPPROTO_IP
#endif
#define SCTP_CLIENT_STREAM_SOCKET_TYPE SOCK_STREAM
#define SCTP_CLIENT_STREAM_SOCKET_PROTOCOL IPPROTO_SCTP
#define RELAY_DGRAM_SOCKET_TYPE SOCK_DGRAM
#define RELAY_DGRAM_SOCKET_PROTOCOL IPPROTO_IP

Loading…
Cancel
Save