diff --git a/src/apps/common/apputils.c b/src/apps/common/apputils.c index b8da9a9..c9d7b7f 100644 --- a/src/apps/common/apputils.c +++ b/src/apps/common/apputils.c @@ -56,6 +56,10 @@ #include #include +#if !defined(TURN_NO_SCTP) && defined(TURN_SCTP_INCLUDE) +#include TURN_SCTP_INCLUDE +#endif + /************************/ int IS_TURN_SERVER = 0; @@ -119,16 +123,18 @@ int set_sock_buf_size(evutil_socket_t fd, int sz0) return 0; } -int socket_tcp_set_keepalive(evutil_socket_t fd) +int socket_tcp_set_keepalive(evutil_socket_t fd,SOCKET_TYPE st) { + UNUSED_ARG(st); + #ifdef SO_KEEPALIVE /* Set the keepalive option active */ - { - int on = 1; - setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (const void*)&on, (socklen_t) sizeof(on)); - } + { + int on = 1; + setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (const void*)&on, (socklen_t) sizeof(on)); + } #else - UNUSED_ARG(fd); + UNUSED_ARG(fd); #endif #ifdef SO_NOSIGPIPE @@ -141,8 +147,9 @@ int socket_tcp_set_keepalive(evutil_socket_t fd) return 0; } -int socket_set_reusable(evutil_socket_t fd, int flag) +int socket_set_reusable(evutil_socket_t fd, int flag, SOCKET_TYPE st) { + UNUSED_ARG(st); if (fd < 0) return -1; @@ -170,6 +177,17 @@ int socket_set_reusable(evutil_socket_t fd, int flag) } #endif +#if defined(SCTP_REUSE_PORT) + if (use_reuseaddr) { + if((st == SCTP_SOCKET)||(st==TLS_SCTP_SOCKET)||(st==TENTATIVE_SCTP_SOCKET)) { + int on = flag; + int ret = setsockopt(fd, IPPROTO_SCTP, SCTP_REUSE_PORT, (const void*) &on, (socklen_t) sizeof(on)); + if (ret < 0) + perror("SCTP_REUSE_PORT"); + } + } +#endif + return 0; } } @@ -229,7 +247,7 @@ int addr_connect(evutil_socket_t fd, const ioa_addr* addr, int *out_errno) } } -int addr_bind(evutil_socket_t fd, const ioa_addr* addr, int reusable, int debug) +int addr_bind(evutil_socket_t fd, const ioa_addr* addr, int reusable, int debug, SOCKET_TYPE st) { if (!addr || fd < 0) { @@ -239,7 +257,7 @@ int addr_bind(evutil_socket_t fd, const ioa_addr* addr, int reusable, int debug) int ret = -1; - socket_set_reusable(fd, reusable); + socket_set_reusable(fd, reusable, st); if (addr->ss.sa_family == AF_INET) { do { diff --git a/src/apps/common/apputils.h b/src/apps/common/apputils.h index 9d87115..dd86d67 100644 --- a/src/apps/common/apputils.h +++ b/src/apps/common/apputils.h @@ -37,6 +37,7 @@ #include "ns_turn_ioaddr.h" #include "ns_turn_msg_defs.h" +#include "ns_turn_ioalib.h" #ifdef __cplusplus extern "C" { @@ -173,14 +174,14 @@ void read_spare_buffer(evutil_socket_t fd); int set_sock_buf_size(evutil_socket_t fd, int sz); -int socket_set_reusable(evutil_socket_t fd, int reusable); +int socket_set_reusable(evutil_socket_t fd, int reusable, SOCKET_TYPE st); int sock_bind_to_device(evutil_socket_t fd, const unsigned char* ifname); int socket_set_nonblocking(evutil_socket_t fd); -int socket_tcp_set_keepalive(evutil_socket_t fd); +int socket_tcp_set_keepalive(evutil_socket_t fd, SOCKET_TYPE st); int addr_connect(evutil_socket_t fd, const ioa_addr* addr, int *out_errno); -int addr_bind(evutil_socket_t fd, const ioa_addr* addr, int reusable, int debug); +int addr_bind(evutil_socket_t fd, const ioa_addr* addr, int reusable, int debug, SOCKET_TYPE st); int addr_get_from_sock(evutil_socket_t fd, ioa_addr *addr); diff --git a/src/apps/peer/udpserver.c b/src/apps/peer/udpserver.c index d1b6b51..b95bcdb 100644 --- a/src/apps/peer/udpserver.c +++ b/src/apps/peer/udpserver.c @@ -86,7 +86,7 @@ static int udp_create_server_socket(server_type* server, set_sock_buf_size(udp_fd,UR_SERVER_SOCK_BUF_SIZE); - if(addr_bind(udp_fd,server_addr,1,1)<0) return -1; + if(addr_bind(udp_fd,server_addr,1,1,UDP_SOCKET)<0) return -1; socket_set_nonblocking(udp_fd); diff --git a/src/apps/relay/dtls_listener.c b/src/apps/relay/dtls_listener.c index 7c4d590..80aeb82 100644 --- a/src/apps/relay/dtls_listener.c +++ b/src/apps/relay/dtls_listener.c @@ -509,7 +509,7 @@ static int create_new_connected_udp_socket( ret->local_addr_known = 1; addr_cpy(&(ret->local_addr), &(s->local_addr)); - if (addr_bind(udp_fd,&(s->local_addr),1,1) < 0) { + if (addr_bind(udp_fd,&(s->local_addr),1,1,UDP_SOCKET) < 0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot bind new detached udp server socket to local addr\n"); IOA_CLOSE_SOCKET(ret); @@ -773,7 +773,7 @@ static int create_server_socket(dtls_listener_relay_server_type* server, int rep int addr_bind_cycle = 0; retry_addr_bind: - if(addr_bind(udp_listen_fd,&server->addr,1,1)<0) { + if(addr_bind(udp_listen_fd,&server->addr,1,1,UDP_SOCKET)<0) { perror("Cannot bind local socket to addr"); char saddr[129]; addr_to_string(&server->addr,(u08bits*)saddr); @@ -851,7 +851,7 @@ static int reopen_server_socket(dtls_listener_relay_server_type* server, evutil_ server->ifname); } - if(addr_bind(udp_listen_fd,&server->addr,1,1)<0) { + if(addr_bind(udp_listen_fd,&server->addr,1,1,UDP_SOCKET)<0) { perror("Cannot bind local socket to addr"); char saddr[129]; addr_to_string(&server->addr,(u08bits*)saddr); diff --git a/src/apps/relay/ns_ioalib_engine_impl.c b/src/apps/relay/ns_ioalib_engine_impl.c index 7622d97..2deca3e 100644 --- a/src/apps/relay/ns_ioalib_engine_impl.c +++ b/src/apps/relay/ns_ioalib_engine_impl.c @@ -816,14 +816,14 @@ int set_raw_socket_tos_options(evutil_socket_t fd, int family) return 0; } -int set_socket_options_fd(evutil_socket_t fd, int tcp, int family) +int set_socket_options_fd(evutil_socket_t fd, SOCKET_TYPE st, int family) { if(fd<0) return 0; set_sock_buf_size(fd,UR_CLIENT_SOCK_BUF_SIZE); - if(tcp) { + if(is_stream_socket(st)) { struct linger so_linger; so_linger.l_onoff = 1; so_linger.l_linger = 0; @@ -839,7 +839,7 @@ int set_socket_options_fd(evutil_socket_t fd, int tcp, int family) socket_set_nonblocking(fd); - if (!tcp) { + if (!is_stream_socket(st)) { set_raw_socket_ttl_options(fd, family); set_raw_socket_tos_options(fd, family); @@ -868,12 +868,14 @@ int set_socket_options_fd(evutil_socket_t fd, int tcp, int family) } else { int flag = 1; - if(setsockopt(fd, /* socket affected */ + + if((st == TENTATIVE_TCP_SOCKET)||(st == TCP_SOCKET)||(st == TLS_SOCKET)) { + setsockopt(fd, /* socket affected */ IPPROTO_TCP, /* set option at TCP level */ TCP_NODELAY, /* name of option */ (char*)&flag, /* value */ - sizeof(int))<0) { /* length of option value */ - + sizeof(int)); /* length of option value */ + } else { #if defined(SCTP_NODELAY) setsockopt(fd, /* socket affected */ IPPROTO_SCTP, /* set option at TCP level */ @@ -881,10 +883,9 @@ int set_socket_options_fd(evutil_socket_t fd, int tcp, int family) (char*)&flag, /* value */ sizeof(int)); /* length of option value */ #endif - } - socket_tcp_set_keepalive(fd); + socket_tcp_set_keepalive(fd,st); } return 0; @@ -895,7 +896,7 @@ int set_socket_options(ioa_socket_handle s) if(!s || (s->parent_s)) return 0; - set_socket_options_fd(s->fd,is_stream_socket(s->st),s->family); + set_socket_options_fd(s->fd,s->st,s->family); s->default_ttl = get_raw_socket_ttl(s->fd, s->family); s->current_ttl = s->default_ttl; @@ -998,7 +999,7 @@ static int bind_ioa_socket(ioa_socket_handle s, const ioa_addr* local_addr, int if (s && s->fd >= 0 && s->e && local_addr) { - int res = addr_bind(s->fd, local_addr, reusable,1); + int res = addr_bind(s->fd, local_addr, reusable,1,s->st); if (res >= 0) { s->bound = 1; addr_cpy(&(s->local_addr), local_addr); @@ -1656,7 +1657,7 @@ ioa_socket_handle detach_ioa_socket(ioa_socket_handle s) TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot bind udp server socket to device %s\n",(char*)(s->e->relay_ifname)); } - if(addr_bind(udp_fd,&(s->local_addr),1,1)<0) { + if(addr_bind(udp_fd,&(s->local_addr),1,1,UDP_SOCKET)<0) { TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot bind new detached udp server socket to local addr\n"); close(udp_fd); return ret; diff --git a/src/apps/relay/ns_ioalib_impl.h b/src/apps/relay/ns_ioalib_impl.h index 21b7fe3..f2e2cee 100644 --- a/src/apps/relay/ns_ioalib_impl.h +++ b/src/apps/relay/ns_ioalib_impl.h @@ -299,7 +299,7 @@ int ssl_read(evutil_socket_t fd, SSL* ssl, ioa_network_buffer_handle nbh, int ve int set_raw_socket_ttl_options(evutil_socket_t fd, int family); int set_raw_socket_tos_options(evutil_socket_t fd, int family); -int set_socket_options_fd(evutil_socket_t fd, int tcp, int family); +int set_socket_options_fd(evutil_socket_t fd, SOCKET_TYPE st, int family); int set_socket_options(ioa_socket_handle s); int send_session_cancellation_to_relay(turnsession_id sid); diff --git a/src/apps/relay/tls_listener.c b/src/apps/relay/tls_listener.c index 4f27cdc..bacf84d 100644 --- a/src/apps/relay/tls_listener.c +++ b/src/apps/relay/tls_listener.c @@ -213,7 +213,7 @@ static int create_server_listener(tls_listener_relay_server_type* server) { int addr_bind_cycle = 0; retry_addr_bind: - if(addr_bind(tls_listen_fd,&server->addr,1,1)<0) { + if(addr_bind(tls_listen_fd,&server->addr,1,1,TCP_SOCKET)<0) { perror("Cannot bind local socket to addr"); char saddr[129]; addr_to_string(&server->addr,(u08bits*)saddr); @@ -228,7 +228,7 @@ static int create_server_listener(tls_listener_relay_server_type* server) { } } - socket_tcp_set_keepalive(tls_listen_fd); + socket_tcp_set_keepalive(tls_listen_fd,TCP_SOCKET); socket_set_nonblocking(tls_listen_fd); @@ -275,12 +275,12 @@ static int sctp_create_server_listener(tls_listener_relay_server_type* server) { 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)<0) { + if(addr_bind(tls_listen_fd,&server->addr,1,0,SCTP_SOCKET)<0) { close(tls_listen_fd); return -1; } - socket_tcp_set_keepalive(tls_listen_fd); + socket_tcp_set_keepalive(tls_listen_fd,SCTP_SOCKET); socket_set_nonblocking(tls_listen_fd); diff --git a/src/apps/relay/turn_admin_server.c b/src/apps/relay/turn_admin_server.c index d9c4cb4..1e9aeed 100644 --- a/src/apps/relay/turn_admin_server.c +++ b/src/apps/relay/turn_admin_server.c @@ -1163,7 +1163,7 @@ static void cliserver_input_handler(struct evconnlistener *l, evutil_socket_t fd clisession->rp = get_realm(NULL); - set_socket_options_fd(fd, 1, sa->sa_family); + set_socket_options_fd(fd, TCP_SOCKET, sa->sa_family); clisession->fd = fd; @@ -1251,7 +1251,7 @@ void setup_admin_thread(void) return; } - if(addr_bind(adminserver.listen_fd,&cli_addr,1,1)<0) { + if(addr_bind(adminserver.listen_fd,&cli_addr,1,1,TCP_SOCKET)<0) { perror("Cannot bind CLI socket to addr"); char saddr[129]; addr_to_string(&cli_addr,(u08bits*)saddr); @@ -1260,7 +1260,7 @@ void setup_admin_thread(void) return; } - socket_tcp_set_keepalive(adminserver.listen_fd); + socket_tcp_set_keepalive(adminserver.listen_fd,TCP_SOCKET); socket_set_nonblocking(adminserver.listen_fd); diff --git a/src/apps/stunclient/stunclient.c b/src/apps/stunclient/stunclient.c index 5f6e005..85457a2 100644 --- a/src/apps/stunclient/stunclient.c +++ b/src/apps/stunclient/stunclient.c @@ -263,7 +263,7 @@ static int run_stunclient(const char* rip, int rport, int *port, int *rfc5780, i err(-1, NULL); if (!addr_any(&real_local_addr)) { - if (addr_bind(udp_fd, &real_local_addr,0,1) < 0) + if (addr_bind(udp_fd, &real_local_addr,0,1,UDP_SOCKET) < 0) err(-1, NULL); } } @@ -276,7 +276,7 @@ static int run_stunclient(const char* rip, int rport, int *port, int *rfc5780, i addr_set_port(&real_local_addr, response_port); - if (addr_bind(new_udp_fd, &real_local_addr,0,1) < 0) + if (addr_bind(new_udp_fd, &real_local_addr,0,1,UDP_SOCKET) < 0) err(-1, NULL); } diff --git a/src/apps/uclient/startuclient.c b/src/apps/uclient/startuclient.c index 3153dc5..6fdd6d7 100644 --- a/src/apps/uclient/startuclient.c +++ b/src/apps/uclient/startuclient.c @@ -259,7 +259,7 @@ static int clnet_connect(uint16_t clnet_remote_port, const char *remote_address, } } - addr_bind(clnet_fd, &local_addr, 0, 1); + addr_bind(clnet_fd, &local_addr, 0, 1, get_socket_type()); } else if (strlen(local_address) > 0) { @@ -267,7 +267,7 @@ static int clnet_connect(uint16_t clnet_remote_port, const char *remote_address, &local_addr) < 0) return -1; - addr_bind(clnet_fd, &local_addr,0,1); + addr_bind(clnet_fd, &local_addr,0,1,get_socket_type()); } if(clnet_info->is_peer) { @@ -1597,7 +1597,7 @@ void tcp_data_connect(app_ur_session *elem, u32bits cid) addr_set_port(&(elem->pinfo.tcp_conn[i]->tcp_data_local_addr),0); - addr_bind(clnet_fd, &(elem->pinfo.tcp_conn[i]->tcp_data_local_addr), 1, 1); + addr_bind(clnet_fd, &(elem->pinfo.tcp_conn[i]->tcp_data_local_addr), 1, 1, TCP_SOCKET); addr_get_from_sock(clnet_fd,&(elem->pinfo.tcp_conn[i]->tcp_data_local_addr)); @@ -1625,7 +1625,7 @@ void tcp_data_connect(app_ur_session *elem, u32bits cid) addr_set_port(&(elem->pinfo.tcp_conn[i]->tcp_data_local_addr),0); - addr_bind(clnet_fd, &(elem->pinfo.tcp_conn[i]->tcp_data_local_addr),1,1); + addr_bind(clnet_fd, &(elem->pinfo.tcp_conn[i]->tcp_data_local_addr),1,1,TCP_SOCKET); addr_get_from_sock(clnet_fd,&(elem->pinfo.tcp_conn[i]->tcp_data_local_addr)); diff --git a/src/apps/uclient/uclient.c b/src/apps/uclient/uclient.c index e73109a..6c7ea41 100644 --- a/src/apps/uclient/uclient.c +++ b/src/apps/uclient/uclient.c @@ -1702,5 +1702,27 @@ int check_integrity(app_ur_conn_info *clnet_info, stun_buffer *message) return 0; } +SOCKET_TYPE get_socket_type() +{ + if(use_sctp) { + if(use_secure) { + return TLS_SCTP_SOCKET; + } else { + return SCTP_SOCKET; + } + } else if(use_tcp) { + if(use_secure) { + return TLS_SOCKET; + } else { + return TCP_SOCKET; + } + } else { + if(use_secure) { + return DTLS_SOCKET; + } else { + return UDP_SOCKET; + } + } +} /////////////////////////////////////////// diff --git a/src/apps/uclient/uclient.h b/src/apps/uclient/uclient.h index 995f369..decef5e 100644 --- a/src/apps/uclient/uclient.h +++ b/src/apps/uclient/uclient.h @@ -112,6 +112,8 @@ int check_integrity(app_ur_conn_info *clnet_info, stun_buffer *message); void recalculate_restapi_hmac(SHATYPE st); +SOCKET_TYPE get_socket_type(void); + //////////////////////////////////////////// #ifdef __cplusplus