| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952 |
- /*
- * 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 "mainrelay.h"
- //////////// Backward compatibility with OpenSSL 1.0.x //////////////
- #define HAVE_OPENSSL11_API (!(OPENSSL_VERSION_NUMBER < 0x10100001L || defined LIBRESSL_VERSION_NUMBER))
- #ifndef HAVE_SSL_CTX_UP_REF
- #define HAVE_SSL_CTX_UP_REF HAVE_OPENSSL11_API
- #endif
- #if !HAVE_SSL_CTX_UP_REF
- #define SSL_CTX_up_ref(ctx) CRYPTO_add(&(ctx)->references, 1, CRYPTO_LOCK_SSL_CTX)
- #endif
- //////////// Barrier for the threads //////////////
- #if !defined(TURN_NO_THREAD_BARRIERS)
- static unsigned int barrier_count = 0;
- static pthread_barrier_t barrier;
- #endif
- ////////////// Auth Server ////////////////
- typedef unsigned char authserver_id;
- struct auth_server {
- authserver_id id;
- struct event_base* event_base;
- struct bufferevent *in_buf;
- struct bufferevent *out_buf;
- pthread_t thr;
- redis_context_handle rch;
- };
- #define MIN_AUTHSERVER_NUMBER (3)
- static authserver_id authserver_number = MIN_AUTHSERVER_NUMBER;
- static struct auth_server authserver[256];
- //////////////////////////////////////////////
- #define get_real_general_relay_servers_number() (turn_params.general_relay_servers_number > 1 ? turn_params.general_relay_servers_number : 1)
- #define get_real_udp_relay_servers_number() (turn_params.udp_relay_servers_number > 1 ? turn_params.udp_relay_servers_number : 1)
- static struct relay_server *general_relay_servers[1+((turnserver_id)-1)];
- static struct relay_server *udp_relay_servers[1+((turnserver_id)-1)];
- //////////////////////////////////////////////
- static void run_events(struct event_base *eb, ioa_engine_handle e);
- static void setup_relay_server(struct relay_server *rs, ioa_engine_handle e, int to_set_rfc5780);
- /////////////// BARRIERS ///////////////////
- #if !defined(PTHREAD_BARRIER_SERIAL_THREAD)
- #define PTHREAD_BARRIER_SERIAL_THREAD (-1)
- #endif
- static void barrier_wait_func(const char* func, int line)
- {
- #if !defined(TURN_NO_THREAD_BARRIERS)
- int br = 0;
- do {
- br = pthread_barrier_wait(&barrier);
- if ((br < 0)&&(br != PTHREAD_BARRIER_SERIAL_THREAD)) {
- int err = errno;
- perror("barrier wait");
- printf("%s:%s:%d: %d\n", __FUNCTION__, func,line,err);
- }
- } while (((br < 0)&&(br != PTHREAD_BARRIER_SERIAL_THREAD)) && (errno == EINTR));
- #else
- UNUSED_ARG(func);
- UNUSED_ARG(line);
- sleep(5);
- #endif
- }
- #define barrier_wait() barrier_wait_func(__FUNCTION__,__LINE__)
- /////////////// Bandwidth //////////////////
- static pthread_mutex_t mutex_bps;
- static band_limit_t allocate_bps(band_limit_t bps, int positive)
- {
- band_limit_t ret = 0;
- if(bps>0) {
- pthread_mutex_lock(&mutex_bps);
- if(positive) {
- if(!(turn_params.bps_capacity)) {
- ret = bps;
- turn_params.bps_capacity_allocated += ret;
- } else if(turn_params.bps_capacity_allocated < turn_params.bps_capacity) {
- band_limit_t reserve = turn_params.bps_capacity - turn_params.bps_capacity_allocated;
- if(reserve <= bps) {
- ret = reserve;
- turn_params.bps_capacity_allocated = turn_params.bps_capacity;
- } else {
- ret = bps;
- turn_params.bps_capacity_allocated += ret;
- }
- }
- } else {
- if(turn_params.bps_capacity_allocated >= bps) {
- turn_params.bps_capacity_allocated -= bps;
- } else {
- turn_params.bps_capacity_allocated = 0;
- }
- }
- pthread_mutex_unlock(&mutex_bps);
- }
- return ret;
- }
- band_limit_t get_bps_capacity_allocated(void)
- {
- band_limit_t ret = 0;
- pthread_mutex_lock(&mutex_bps);
- ret = turn_params.bps_capacity_allocated;
- pthread_mutex_unlock(&mutex_bps);
- return ret;
- }
- band_limit_t get_bps_capacity(void)
- {
- band_limit_t ret = 0;
- pthread_mutex_lock(&mutex_bps);
- ret = turn_params.bps_capacity;
- pthread_mutex_unlock(&mutex_bps);
- return ret;
- }
- void set_bps_capacity(band_limit_t value)
- {
- pthread_mutex_lock(&mutex_bps);
- turn_params.bps_capacity = value;
- pthread_mutex_unlock(&mutex_bps);
- }
- band_limit_t get_max_bps(void)
- {
- band_limit_t ret = 0;
- pthread_mutex_lock(&mutex_bps);
- ret = turn_params.max_bps;
- pthread_mutex_unlock(&mutex_bps);
- return ret;
- }
- void set_max_bps(band_limit_t value)
- {
- pthread_mutex_lock(&mutex_bps);
- turn_params.max_bps = value;
- pthread_mutex_unlock(&mutex_bps);
- }
- /////////////// AUX SERVERS ////////////////
- static void add_aux_server_list(const char *saddr, turn_server_addrs_list_t *list)
- {
- if(saddr && list) {
- ioa_addr addr;
- if(make_ioa_addr_from_full_string((const uint8_t*)saddr, 0, &addr)!=0) {
- TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong full address format: %s\n",saddr);
- } else {
- list->addrs = (ioa_addr*)realloc(list->addrs,sizeof(ioa_addr)*(list->size+1));
- addr_cpy(&(list->addrs[(list->size)++]),&addr);
- {
- uint8_t s[1025];
- addr_to_string(&addr, s);
- TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Aux server: %s\n",s);
- }
- }
- }
- }
- void add_aux_server(const char *saddr)
- {
- add_aux_server_list(saddr,&turn_params.aux_servers_list);
- }
- /////////////// ALTERNATE SERVERS ////////////////
- static void add_alt_server(const char *saddr, int default_port, turn_server_addrs_list_t *list)
- {
- if(saddr && list) {
- ioa_addr addr;
- turn_mutex_lock(&(list->m));
- if(make_ioa_addr_from_full_string((const uint8_t*)saddr, default_port, &addr)!=0) {
- TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong IP address format: %s\n",saddr);
- } else {
- list->addrs = (ioa_addr*)realloc(list->addrs,sizeof(ioa_addr)*(list->size+1));
- addr_cpy(&(list->addrs[(list->size)++]),&addr);
- {
- uint8_t s[1025];
- addr_to_string(&addr, s);
- TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Alternate server added: %s\n",s);
- }
- }
- turn_mutex_unlock(&(list->m));
- }
- }
- static void del_alt_server(const char *saddr, int default_port, turn_server_addrs_list_t *list)
- {
- if(saddr && list && list->size && list->addrs) {
- ioa_addr addr;
- turn_mutex_lock(&(list->m));
- if(make_ioa_addr_from_full_string((const uint8_t*)saddr, default_port, &addr)!=0) {
- TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong IP address format: %s\n",saddr);
- } else {
- size_t i;
- int found = 0;
- for(i=0;i<list->size;++i) {
- if(addr_eq(&(list->addrs[i]),&addr)) {
- found = 1;
- break;
- }
- }
- if(found) {
- size_t j;
- ioa_addr *new_addrs = (ioa_addr*)malloc(sizeof(ioa_addr)*(list->size-1));
- for(j=0;j<i;++j) {
- addr_cpy(&(new_addrs[j]),&(list->addrs[j]));
- }
- for(j=i;j<list->size-1;++j) {
- addr_cpy(&(new_addrs[j]),&(list->addrs[j+1]));
- }
- free(list->addrs);
- list->addrs = new_addrs;
- list->size -= 1;
- {
- uint8_t s[1025];
- addr_to_string(&addr, s);
- TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Alternate server removed: %s\n",s);
- }
- del_alt_server(saddr, default_port, list);
- }
- }
- turn_mutex_unlock(&(list->m));
- }
- }
- void add_alternate_server(const char *saddr)
- {
- add_alt_server(saddr,DEFAULT_STUN_PORT,&turn_params.alternate_servers_list);
- }
- void del_alternate_server(const char *saddr)
- {
- del_alt_server(saddr,DEFAULT_STUN_PORT,&turn_params.alternate_servers_list);
- }
- void add_tls_alternate_server(const char *saddr)
- {
- add_alt_server(saddr,DEFAULT_STUN_TLS_PORT,&turn_params.tls_alternate_servers_list);
- }
- void del_tls_alternate_server(const char *saddr)
- {
- del_alt_server(saddr,DEFAULT_STUN_TLS_PORT,&turn_params.tls_alternate_servers_list);
- }
- //////////////////////////////////////////////////
- typedef struct update_ssl_ctx_cb_args {
- ioa_engine_handle engine;
- turn_params_t *params;
- struct event *next;
- } update_ssl_ctx_cb_args_t;
- /*
- * Copy SSL context at "from", which may be NULL if no context in use
- */
- static void replace_one_ssl_ctx(SSL_CTX **to, SSL_CTX *from)
- {
- if (*to)
- SSL_CTX_free(*to);
- if (from != NULL)
- SSL_CTX_up_ref(from);
- *to = from;
- }
- /*
- * Synchronise the ioa_engine's SSL certificates with the global ones
- */
- static void update_ssl_ctx(evutil_socket_t sock, short events, update_ssl_ctx_cb_args_t *args)
- {
- ioa_engine_handle e = args->engine;
- turn_params_t *params = args->params;
- /* No mutex with "e" as these are only used in the same event loop */
- pthread_mutex_lock(&turn_params.tls_mutex);
- replace_one_ssl_ctx(&e->tls_ctx_ssl23, params->tls_ctx_ssl23);
- replace_one_ssl_ctx(&e->tls_ctx_v1_0, params->tls_ctx_v1_0);
- #if TLSv1_1_SUPPORTED
- replace_one_ssl_ctx(&e->tls_ctx_v1_1, params->tls_ctx_v1_1);
- #if TLSv1_2_SUPPORTED
- replace_one_ssl_ctx(&e->tls_ctx_v1_2, params->tls_ctx_v1_2);
- #endif
- #endif
- #if DTLS_SUPPORTED
- replace_one_ssl_ctx(&e->dtls_ctx, params->dtls_ctx);
- #endif
- #if DTLSv1_2_SUPPORTED
- replace_one_ssl_ctx(&e->dtls_ctx_v1_2, params->dtls_ctx_v1_2);
- #endif
- struct event *next = args->next;
- pthread_mutex_unlock(&turn_params.tls_mutex);
- if (next != NULL)
- event_active(next, EV_READ, 0);
- UNUSED_ARG(sock);
- UNUSED_ARG(events);
- }
- void set_ssl_ctx(ioa_engine_handle e, turn_params_t *params)
- {
- update_ssl_ctx_cb_args_t *args = (update_ssl_ctx_cb_args_t *)malloc(sizeof(update_ssl_ctx_cb_args_t));
- args->engine = e;
- args->params = params;
- args->next = NULL;
- update_ssl_ctx(-1, 0, args);
- struct event_base *base = e->event_base;
- if (base != NULL) {
- struct event *ev = event_new(base, -1, EV_PERSIST, (event_callback_fn)update_ssl_ctx, (void *)args);
- pthread_mutex_lock(&turn_params.tls_mutex);
- args->next = params->tls_ctx_update_ev;
- params->tls_ctx_update_ev = ev;
- pthread_mutex_unlock(&turn_params.tls_mutex);
- }
- }
- //////////////////////////////////////////////////
- void add_listener_addr(const char* addr) {
- ioa_addr baddr;
- if(make_ioa_addr((const uint8_t*)addr,0,&baddr)<0) {
- TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot add a listener address: %s\n",addr);
- } else {
- char sbaddr[129];
- addr_to_string_no_port(&baddr,(uint8_t*)sbaddr);
- size_t i = 0;
- for(i=0;i<turn_params.listener.addrs_number;++i) {
- if(addr_eq(turn_params.listener.encaddrs[i],&baddr)) {
- return;
- }
- }
- ++turn_params.listener.addrs_number;
- ++turn_params.listener.services_number;
- turn_params.listener.addrs = (char**)realloc(turn_params.listener.addrs, sizeof(char*)*turn_params.listener.addrs_number);
- turn_params.listener.addrs[turn_params.listener.addrs_number-1]=strdup(sbaddr);
- turn_params.listener.encaddrs = (ioa_addr**)realloc(turn_params.listener.encaddrs, sizeof(ioa_addr*)*turn_params.listener.addrs_number);
- turn_params.listener.encaddrs[turn_params.listener.addrs_number-1]=(ioa_addr*)malloc(sizeof(ioa_addr));
- addr_cpy(turn_params.listener.encaddrs[turn_params.listener.addrs_number-1],&baddr);
- TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Listener address to use: %s\n",sbaddr);
- }
- }
- int add_relay_addr(const char* addr) {
- ioa_addr baddr;
- if(make_ioa_addr((const uint8_t*)addr,0,&baddr)<0) {
- TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot add a relay address: %s\n",addr);
- return -1;
- } else {
- char sbaddr[129];
- addr_to_string_no_port(&baddr,(uint8_t*)sbaddr);
- size_t i = 0;
- for(i=0;i<turn_params.relays_number;++i) {
- if(!strcmp(turn_params.relay_addrs[i],sbaddr)) {
- return 0;
- }
- }
- ++turn_params.relays_number;
- turn_params.relay_addrs = (char**)realloc(turn_params.relay_addrs, sizeof(char*)*turn_params.relays_number);
- turn_params.relay_addrs[turn_params.relays_number-1]=strdup(sbaddr);
- TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Relay address to use: %s\n",sbaddr);
- return 1;
- }
- }
- static void allocate_relay_addrs_ports(void) {
- int i;
- TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Wait for relay ports initialization...\n");
- for(i=0;i<(int)turn_params.relays_number;i++) {
- ioa_addr baddr;
- if(make_ioa_addr((const uint8_t*)turn_params.relay_addrs[i],0,&baddr)>=0) {
- TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, " relay %s initialization...\n",turn_params.relay_addrs[i]);
- turnipports_add_ip(STUN_ATTRIBUTE_TRANSPORT_UDP_VALUE, &baddr);
- turnipports_add_ip(STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE, &baddr);
- TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, " relay %s initialization done\n",turn_params.relay_addrs[i]);
- }
- }
- TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Relay ports initialization done\n");
- }
- //////////////////////////////////////////////////
- // communications between listener and relays ==>>
- static int handle_relay_message(relay_server_handle rs, struct message_to_relay *sm);
- static pthread_mutex_t auth_message_counter_mutex = PTHREAD_MUTEX_INITIALIZER;
- static authserver_id auth_message_counter = 1;
- void send_auth_message_to_auth_server(struct auth_message *am)
- {
- pthread_mutex_lock(&auth_message_counter_mutex);
- if(auth_message_counter>=authserver_number) auth_message_counter = 1;
- else if(auth_message_counter<1) auth_message_counter = 1;
- authserver_id sn = auth_message_counter++;
- pthread_mutex_unlock(&auth_message_counter_mutex);
- struct evbuffer *output = bufferevent_get_output(authserver[sn].out_buf);
- if(evbuffer_add(output,am,sizeof(struct auth_message))<0) {
- fprintf(stderr,"%s: Weird buffer error\n",__FUNCTION__);
- }
- }
- static void auth_server_receive_message(struct bufferevent *bev, void *ptr)
- {
- UNUSED_ARG(ptr);
-
- struct auth_message am;
- int n = 0;
- struct evbuffer *input = bufferevent_get_input(bev);
-
- while ((n = evbuffer_remove(input, &am, sizeof(struct auth_message))) > 0) {
- if (n != sizeof(struct auth_message)) {
- fprintf(stderr,"%s: Weird buffer error: size=%d\n",__FUNCTION__,n);
- continue;
- }
-
- {
- hmackey_t key;
- if(get_user_key(am.in_oauth,&(am.out_oauth),&(am.max_session_time),am.username,am.realm,key,am.in_buffer.nbh)<0) {
- am.success = 0;
- } else {
- bcopy(key,am.key,sizeof(hmackey_t));
- am.success = 1;
- }
- }
-
- size_t dest = am.id;
-
- struct evbuffer *output = NULL;
-
- if(dest>=TURNSERVER_ID_BOUNDARY_BETWEEN_TCP_AND_UDP) {
- dest -= TURNSERVER_ID_BOUNDARY_BETWEEN_TCP_AND_UDP;
- if(dest >= get_real_udp_relay_servers_number()) {
- TURN_LOG_FUNC(
- TURN_LOG_LEVEL_ERROR,
- "%s: Too large UDP relay number: %d\n",
- __FUNCTION__,(int)dest);
- } else if(!(udp_relay_servers[dest])) {
- TURN_LOG_FUNC(
- TURN_LOG_LEVEL_ERROR,
- "%s: Wrong UDP relay number: %d, total %d\n",
- __FUNCTION__,(int)dest, (int)get_real_udp_relay_servers_number());
- } else {
- output = bufferevent_get_output(udp_relay_servers[dest]->auth_out_buf);
- }
- } else {
- if(dest >= get_real_general_relay_servers_number()) {
- TURN_LOG_FUNC(
- TURN_LOG_LEVEL_ERROR,
- "%s: Too large general relay number: %d, total %d\n",
- __FUNCTION__,(int)dest,(int)get_real_general_relay_servers_number());
- } else if(!(general_relay_servers[dest])) {
- TURN_LOG_FUNC(
- TURN_LOG_LEVEL_ERROR,
- "%s: Wrong general relay number: %d, total %d\n",
- __FUNCTION__,(int)dest,(int)get_real_general_relay_servers_number());
- } else {
- output = bufferevent_get_output(general_relay_servers[dest]->auth_out_buf);
- }
- }
-
- if(output)
- evbuffer_add(output,&am,sizeof(struct auth_message));
- else {
- ioa_network_buffer_delete(NULL, am.in_buffer.nbh);
- am.in_buffer.nbh = NULL;
- }
- }
- }
- static int send_socket_to_general_relay(ioa_engine_handle e, struct message_to_relay *sm)
- {
- struct relay_server *rdest = sm->relay_server;
- if(!rdest) {
- size_t dest = (hash_int32(addr_get_port(&(sm->m.sm.nd.src_addr)))) % get_real_general_relay_servers_number();
- rdest = general_relay_servers[dest];
- }
- struct message_to_relay *smptr = sm;
- smptr->t = RMT_SOCKET;
- struct evbuffer *output = NULL;
- int success = 0;
- if(!rdest) {
- goto label_end;
- }
- output = bufferevent_get_output(rdest->out_buf);
- if(output) {
- if(evbuffer_add(output,smptr,sizeof(struct message_to_relay))<0) {
- TURN_LOG_FUNC(
- TURN_LOG_LEVEL_ERROR,
- "%s: Cannot add message to relay output buffer\n",
- __FUNCTION__);
- } else {
- success = 1;
- smptr->m.sm.nd.nbh=NULL;
- }
- }
- label_end:
- if(!success) {
- ioa_network_buffer_delete(e, smptr->m.sm.nd.nbh);
- smptr->m.sm.nd.nbh=NULL;
- IOA_CLOSE_SOCKET(smptr->m.sm.s);
- return -1;
- }
- return 0;
- }
- static int send_socket_to_relay(turnserver_id id, uint64_t cid, stun_tid *tid, ioa_socket_handle s,
- int message_integrity, MESSAGE_TO_RELAY_TYPE rmt, ioa_net_data *nd,
- int can_resume)
- {
- int ret = -1;
- struct message_to_relay sm;
- bzero(&sm,sizeof(struct message_to_relay));
- sm.t = rmt;
- ioa_socket_handle s_to_delete = s;
- struct relay_server *rs = NULL;
- if(id>=TURNSERVER_ID_BOUNDARY_BETWEEN_TCP_AND_UDP) {
- size_t dest = id-TURNSERVER_ID_BOUNDARY_BETWEEN_TCP_AND_UDP;
- if(dest >= get_real_udp_relay_servers_number()) {
- TURN_LOG_FUNC(
- TURN_LOG_LEVEL_ERROR,
- "%s: Too large UDP relay number: %d, rmt=%d, total=%d\n",
- __FUNCTION__,(int)dest,(int)rmt, (int)get_real_udp_relay_servers_number());
- goto err;
- }
- rs = udp_relay_servers[dest];
- if(!rs) {
- TURN_LOG_FUNC(
- TURN_LOG_LEVEL_ERROR,
- "%s: Wrong UDP relay number: %d, rmt=%d, total=%d\n",
- __FUNCTION__,(int)dest,(int)rmt, (int)get_real_udp_relay_servers_number());
- goto err;
- }
- } else {
- size_t dest = id;
- if(dest >= get_real_general_relay_servers_number()) {
- TURN_LOG_FUNC(
- TURN_LOG_LEVEL_ERROR,
- "%s: Too large general relay number: %d, rmt=%d, total=%d\n",
- __FUNCTION__,(int)dest,(int)rmt, (int)get_real_general_relay_servers_number());
- goto err;
- }
- rs = general_relay_servers[dest];
- if(!rs) {
- TURN_LOG_FUNC(
- TURN_LOG_LEVEL_ERROR,
- "%s: Wrong general relay number: %d, rmt=%d, total=%d\n",
- __FUNCTION__,(int)dest,(int)rmt, (int)get_real_general_relay_servers_number());
- goto err;
- }
- }
- switch (rmt) {
- case(RMT_CB_SOCKET): {
- if(nd && nd->nbh) {
- sm.m.cb_sm.id = id;
- sm.m.cb_sm.connection_id = (tcp_connection_id)cid;
- stun_tid_cpy(&(sm.m.cb_sm.tid),tid);
- sm.m.cb_sm.s = s;
- sm.m.cb_sm.message_integrity = message_integrity;
- addr_cpy(&(sm.m.cb_sm.nd.src_addr),&(nd->src_addr));
- sm.m.cb_sm.nd.recv_tos = nd->recv_tos;
- sm.m.cb_sm.nd.recv_ttl = nd->recv_ttl;
- sm.m.cb_sm.nd.nbh = nd->nbh;
- sm.m.cb_sm.can_resume = can_resume;
- nd->nbh = NULL;
- s_to_delete = NULL;
- ret = 0;
- }
- break;
- }
- case (RMT_MOBILE_SOCKET): {
- if(nd && nd->nbh) {
- sm.m.sm.s = s;
- addr_cpy(&(sm.m.sm.nd.src_addr),&(nd->src_addr));
- sm.m.sm.nd.recv_tos = nd->recv_tos;
- sm.m.sm.nd.recv_ttl = nd->recv_ttl;
- sm.m.sm.nd.nbh = nd->nbh;
- sm.m.sm.can_resume = can_resume;
- nd->nbh = NULL;
- s_to_delete = NULL;
- ret = 0;
- } else {
- TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Empty buffer with mobile socket\n",__FUNCTION__);
- }
- break;
- }
- default: {
- TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: UNKNOWN RMT message: %d\n",__FUNCTION__,(int)rmt);
- }
- }
- if(ret == 0) {
- struct evbuffer *output = bufferevent_get_output(rs->out_buf);
- if(output) {
- evbuffer_add(output,&sm,sizeof(struct message_to_relay));
- } else {
- TURN_LOG_FUNC(
- TURN_LOG_LEVEL_ERROR,
- "%s: Empty output buffer\n",
- __FUNCTION__);
- ret = -1;
- s_to_delete = s;
- }
- }
- err:
- IOA_CLOSE_SOCKET(s_to_delete);
- if(nd && nd->nbh) {
- ioa_network_buffer_delete(NULL, nd->nbh);
- nd->nbh = NULL;
- }
- if(ret<0) {
- if(rmt == RMT_MOBILE_SOCKET) {
- ioa_network_buffer_delete(NULL, sm.m.sm.nd.nbh);
- sm.m.sm.nd.nbh = NULL;
- } else if(rmt == RMT_CB_SOCKET) {
- ioa_network_buffer_delete(NULL, sm.m.cb_sm.nd.nbh);
- sm.m.cb_sm.nd.nbh = NULL;
- }
- }
- return ret;
- }
- int send_session_cancellation_to_relay(turnsession_id sid)
- {
- int ret = 0;
- struct message_to_relay sm;
- bzero(&sm,sizeof(struct message_to_relay));
- sm.t = RMT_CANCEL_SESSION;
- turnserver_id id = (turnserver_id)(sid / TURN_SESSION_ID_FACTOR);
- struct relay_server *rs = NULL;
- if(id>=TURNSERVER_ID_BOUNDARY_BETWEEN_TCP_AND_UDP) {
- size_t dest = id-TURNSERVER_ID_BOUNDARY_BETWEEN_TCP_AND_UDP;
- if(dest >= get_real_udp_relay_servers_number()) {
- TURN_LOG_FUNC(
- TURN_LOG_LEVEL_ERROR,
- "%s: Too large UDP relay number: %d, total=%d\n",
- __FUNCTION__,(int)dest,(int)get_real_udp_relay_servers_number());
- ret = -1;
- goto err;
- }
- rs = udp_relay_servers[dest];
- if(!rs) {
- TURN_LOG_FUNC(
- TURN_LOG_LEVEL_ERROR,
- "%s: Wrong UDP relay number: %d, total=%d\n",
- __FUNCTION__,(int)dest,(int)get_real_udp_relay_servers_number());
- ret = -1;
- goto err;
- }
- } else {
- size_t dest = id;
- if(dest >= get_real_general_relay_servers_number()) {
- TURN_LOG_FUNC(
- TURN_LOG_LEVEL_ERROR,
- "%s: Too large general relay number: %d, total=%d\n",
- __FUNCTION__,(int)dest,(int)get_real_general_relay_servers_number());
- ret = -1;
- goto err;
- }
- rs = general_relay_servers[dest];
- if(!rs) {
- TURN_LOG_FUNC(
- TURN_LOG_LEVEL_ERROR,
- "%s: Wrong general relay number: %d, total=%d\n",
- __FUNCTION__,(int)dest,(int)get_real_general_relay_servers_number());
- ret = -1;
- goto err;
- }
- }
- sm.relay_server = rs;
- sm.m.csm.id = sid;
- {
- struct evbuffer *output = bufferevent_get_output(rs->out_buf);
- if(output) {
- evbuffer_add(output,&sm,sizeof(struct message_to_relay));
- } else {
- TURN_LOG_FUNC(
- TURN_LOG_LEVEL_ERROR,
- "%s: Empty output buffer\n",
- __FUNCTION__);
- ret = -1;
- }
- }
- err:
- return ret;
- }
- static int handle_relay_message(relay_server_handle rs, struct message_to_relay *sm)
- {
- if(rs && sm) {
- switch (sm->t) {
- case RMT_CANCEL_SESSION: {
- turn_cancel_session(&(rs->server),sm->m.csm.id);
- }
- break;
- case RMT_SOCKET: {
- if (sm->m.sm.s->defer_nbh) {
- if (!sm->m.sm.nd.nbh) {
- sm->m.sm.nd.nbh = sm->m.sm.s->defer_nbh;
- sm->m.sm.s->defer_nbh = NULL;
- } else {
- ioa_network_buffer_delete(rs->ioa_eng, sm->m.sm.s->defer_nbh);
- sm->m.sm.s->defer_nbh = NULL;
- }
- }
- ioa_socket_handle s = sm->m.sm.s;
- if (!s) {
- TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
- "%s: socket EMPTY\n",__FUNCTION__);
- } else if (s->read_event || s->bev) {
- TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
- "%s: socket wrongly preset: 0x%lx : 0x%lx\n",
- __FUNCTION__, (long) s->read_event, (long) s->bev);
- IOA_CLOSE_SOCKET(s);
- sm->m.sm.s = NULL;
- } else {
- s->e = rs->ioa_eng;
- if(open_client_connection_session(&(rs->server), &(sm->m.sm))<0) {
- IOA_CLOSE_SOCKET(s);
- sm->m.sm.s = NULL;
- }
- }
- ioa_network_buffer_delete(rs->ioa_eng, sm->m.sm.nd.nbh);
- sm->m.sm.nd.nbh = NULL;
- }
- break;
- case RMT_CB_SOCKET:
- turnserver_accept_tcp_client_data_connection(&(rs->server), sm->m.cb_sm.connection_id,
- &(sm->m.cb_sm.tid), sm->m.cb_sm.s, sm->m.cb_sm.message_integrity, &(sm->m.cb_sm.nd),
- /*sm->m.cb_sm.can_resume*/
- /* Note: we cannot resume this call, it must be authenticated in-place.
- * There are two reasons for that:
- * 1) Technical. That's very difficult with the current code structure.
- * 2) Security (more important). We do not want 'stealing' connections between the users.
- * */
- 0);
- ioa_network_buffer_delete(rs->ioa_eng, sm->m.cb_sm.nd.nbh);
- sm->m.cb_sm.nd.nbh = NULL;
- break;
- case RMT_MOBILE_SOCKET: {
- ioa_socket_handle s = sm->m.sm.s;
- if (!s) {
- TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
- "%s: mobile socket EMPTY\n",__FUNCTION__);
- } else if (s->read_event || s->bev) {
- TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
- "%s: mobile socket wrongly preset: 0x%lx : 0x%lx\n",
- __FUNCTION__, (long) s->read_event, (long) s->bev);
- IOA_CLOSE_SOCKET(s);
- sm->m.sm.s = NULL;
- } else {
- s->e = rs->ioa_eng;
- if(open_client_connection_session(&(rs->server), &(sm->m.sm))<0) {
- IOA_CLOSE_SOCKET(s);
- sm->m.sm.s = NULL;
- }
- }
- ioa_network_buffer_delete(rs->ioa_eng, sm->m.sm.nd.nbh);
- sm->m.sm.nd.nbh = NULL;
- break;
- }
- default: {
- perror("Weird buffer type\n");
- }
- }
- }
- return 0;
- }
- static void handle_relay_auth_message(struct relay_server *rs, struct auth_message *am)
- {
- am->resume_func(am->success, am->out_oauth, am->max_session_time, am->key, am->pwd,
- &(rs->server), am->ctxkey, &(am->in_buffer), am->realm);
- if (am->in_buffer.nbh) {
- ioa_network_buffer_delete(rs->ioa_eng, am->in_buffer.nbh);
- am->in_buffer.nbh = NULL;
- }
- }
- static void relay_receive_message(struct bufferevent *bev, void *ptr)
- {
- struct message_to_relay sm;
- int n = 0;
- struct evbuffer *input = bufferevent_get_input(bev);
- struct relay_server *rs = (struct relay_server *)ptr;
- while ((n = evbuffer_remove(input, &sm, sizeof(struct message_to_relay))) > 0) {
- if (n != sizeof(struct message_to_relay)) {
- perror("Weird buffer error\n");
- continue;
- }
- handle_relay_message(rs, &sm);
- }
- }
- static void relay_receive_auth_message(struct bufferevent *bev, void *ptr)
- {
- struct auth_message am;
- int n = 0;
- struct evbuffer *input = bufferevent_get_input(bev);
- struct relay_server *rs = (struct relay_server *)ptr;
- while ((n = evbuffer_remove(input, &am, sizeof(struct auth_message))) > 0) {
- if (n != sizeof(struct auth_message)) {
- perror("Weird auth_buffer error\n");
- continue;
- }
- handle_relay_auth_message(rs, &am);
- }
- }
- static int send_message_from_listener_to_client(ioa_engine_handle e, ioa_network_buffer_handle nbh, ioa_addr *origin, ioa_addr *destination)
- {
- struct message_to_listener mm;
- mm.t = LMT_TO_CLIENT;
- addr_cpy(&(mm.m.tc.origin),origin);
- addr_cpy(&(mm.m.tc.destination),destination);
- mm.m.tc.nbh = ioa_network_buffer_allocate(e);
- ioa_network_buffer_header_init(mm.m.tc.nbh);
- bcopy(ioa_network_buffer_data(nbh),ioa_network_buffer_data(mm.m.tc.nbh),ioa_network_buffer_get_size(nbh));
- ioa_network_buffer_set_size(mm.m.tc.nbh,ioa_network_buffer_get_size(nbh));
- struct evbuffer *output = bufferevent_get_output(turn_params.listener.out_buf);
- evbuffer_add(output,&mm,sizeof(struct message_to_listener));
- return 0;
- }
- static void listener_receive_message(struct bufferevent *bev, void *ptr)
- {
- UNUSED_ARG(ptr);
- struct message_to_listener mm;
- int n = 0;
- struct evbuffer *input = bufferevent_get_input(bev);
- while ((n = evbuffer_remove(input, &mm, sizeof(struct message_to_listener))) > 0) {
- if (n != sizeof(struct message_to_listener)) {
- perror("Weird buffer error\n");
- continue;
- }
- if (mm.t != LMT_TO_CLIENT) {
- perror("Weird buffer type\n");
- continue;
- }
- size_t relay_thread_index = 0;
- if(turn_params.net_engine_version == NEV_UDP_SOCKET_PER_THREAD) {
- size_t ri;
- for(ri=0;ri<get_real_general_relay_servers_number();ri++) {
- if(!(general_relay_servers[ri])) {
- TURN_LOG_FUNC(
- TURN_LOG_LEVEL_ERROR,
- "%s: Wrong general relay number: %d, total %d\n",
- __FUNCTION__,(int)ri,(int)get_real_general_relay_servers_number());
- } else if(general_relay_servers[ri]->thr == pthread_self()) {
- relay_thread_index=ri;
- break;
- }
- }
- }
- size_t i;
- int found = 0;
- for(i=0;i<turn_params.listener.addrs_number;i++) {
- if(addr_eq_no_port(turn_params.listener.encaddrs[i],&mm.m.tc.origin)) {
- int o_port = addr_get_port(&mm.m.tc.origin);
- if(turn_params.listener.addrs_number == turn_params.listener.services_number) {
- if(o_port == turn_params.listener_port) {
- if(turn_params.listener.udp_services && turn_params.listener.udp_services[i] && turn_params.listener.udp_services[i][relay_thread_index]) {
- found = 1;
- udp_send_message(turn_params.listener.udp_services[i][relay_thread_index], mm.m.tc.nbh, &mm.m.tc.destination);
- }
- } else {
- TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"%s: Wrong origin port(1): %d\n",__FUNCTION__,o_port);
- }
- } else if((turn_params.listener.addrs_number * 2) == turn_params.listener.services_number) {
- if(o_port == turn_params.listener_port) {
- if(turn_params.listener.udp_services && turn_params.listener.udp_services[i*2] && turn_params.listener.udp_services[i*2][relay_thread_index]) {
- found = 1;
- udp_send_message(turn_params.listener.udp_services[i*2][relay_thread_index], mm.m.tc.nbh, &mm.m.tc.destination);
- }
- } else if(o_port == get_alt_listener_port()) {
- if(turn_params.listener.udp_services && turn_params.listener.udp_services[i*2+1] && turn_params.listener.udp_services[i*2+1][relay_thread_index]) {
- found = 1;
- udp_send_message(turn_params.listener.udp_services[i*2+1][relay_thread_index], mm.m.tc.nbh, &mm.m.tc.destination);
- }
- } else {
- TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"%s: Wrong origin port(2): %d\n",__FUNCTION__,o_port);
- }
- } else {
- TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"%s: Wrong listener setup\n",__FUNCTION__);
- }
- break;
- }
- }
- if(!found) {
- uint8_t saddr[129];
- addr_to_string(&mm.m.tc.origin, saddr);
- TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"%s: Cannot find local source %s\n",__FUNCTION__,saddr);
- }
- ioa_network_buffer_delete(turn_params.listener.ioa_eng, mm.m.tc.nbh);
- mm.m.tc.nbh = NULL;
- }
- }
- // <<== communications between listener and relays
- static ioa_engine_handle create_new_listener_engine(void)
- {
- struct event_base *eb = turn_event_base_new();
- TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"IO method (udp listener/relay thread): %s\n",event_base_get_method(eb));
- super_memory_t* sm = new_super_memory_region();
- ioa_engine_handle e = create_ioa_engine(sm, eb, turn_params.listener.tp, turn_params.relay_ifname, turn_params.relays_number, turn_params.relay_addrs,
- turn_params.default_relays, turn_params.verbose
- #if !defined(TURN_NO_HIREDIS)
- ,turn_params.redis_statsdb
- #endif
- );
- set_ssl_ctx(e, &turn_params);
- ioa_engine_set_rtcp_map(e, turn_params.listener.rtcpmap);
- return e;
- }
- static void *run_udp_listener_thread(void *arg)
- {
- static int always_true = 1;
- ignore_sigpipe();
- barrier_wait();
- dtls_listener_relay_server_type *server = (dtls_listener_relay_server_type *)arg;
- while(always_true && server) {
- run_events(NULL, get_engine(server));
- }
- return arg;
- }
- static void setup_listener(void)
- {
- super_memory_t* sm = new_super_memory_region();
- turn_params.listener.tp = turnipports_create(sm, turn_params.min_port, turn_params.max_port);
- turn_params.listener.event_base = turn_event_base_new();
- TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"IO method (main listener thread): %s\n",event_base_get_method(turn_params.listener.event_base));
- turn_params.listener.ioa_eng = create_ioa_engine(sm, turn_params.listener.event_base, turn_params.listener.tp,
- turn_params.relay_ifname, turn_params.relays_number, turn_params.relay_addrs,
- turn_params.default_relays, turn_params.verbose
- #if !defined(TURN_NO_HIREDIS)
- ,turn_params.redis_statsdb
- #endif
- );
- if(!turn_params.listener.ioa_eng)
- exit(-1);
- set_ssl_ctx(turn_params.listener.ioa_eng, &turn_params);
- turn_params.listener.rtcpmap = rtcp_map_create(turn_params.listener.ioa_eng);
- ioa_engine_set_rtcp_map(turn_params.listener.ioa_eng, turn_params.listener.rtcpmap);
- {
- struct bufferevent *pair[2];
- bufferevent_pair_new(turn_params.listener.event_base, TURN_BUFFEREVENTS_OPTIONS, pair);
- turn_params.listener.in_buf = pair[0];
- turn_params.listener.out_buf = pair[1];
- bufferevent_setcb(turn_params.listener.in_buf, listener_receive_message, NULL, NULL, &turn_params.listener);
- bufferevent_enable(turn_params.listener.in_buf, EV_READ);
- }
- if (turn_params.rfc5780 == 1) {
- if(turn_params.listener.addrs_number<2 || turn_params.external_ip) {
- turn_params.rfc5780 = 0;
- TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: I cannot support STUN CHANGE_REQUEST functionality because only one IP address is provided\n");
- } else {
- turn_params.listener.services_number = turn_params.listener.services_number * 2;
- }
- } else {
- TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "INFO: RFC5780 disabled! /NAT behavior discovery/\n");
- }
- turn_params.listener.udp_services = (dtls_listener_relay_server_type***)allocate_super_memory_engine(turn_params.listener.ioa_eng, sizeof(dtls_listener_relay_server_type**)*turn_params.listener.services_number);
- turn_params.listener.dtls_services = (dtls_listener_relay_server_type***)allocate_super_memory_engine(turn_params.listener.ioa_eng, sizeof(dtls_listener_relay_server_type**)*turn_params.listener.services_number);
- turn_params.listener.aux_udp_services = (dtls_listener_relay_server_type***)allocate_super_memory_engine(turn_params.listener.ioa_eng, (sizeof(dtls_listener_relay_server_type**)*turn_params.aux_servers_list.size)+sizeof(void*));
- }
- static void setup_barriers(void)
- {
- /* Adjust barriers: */
- #if !defined(TURN_NO_THREAD_BARRIERS)
- if((turn_params.net_engine_version == NEV_UDP_SOCKET_PER_ENDPOINT) && turn_params.general_relay_servers_number>1) {
- /* UDP: */
- if(!turn_params.no_udp) {
- barrier_count += turn_params.listener.addrs_number;
- if(turn_params.rfc5780) {
- barrier_count += turn_params.listener.addrs_number;
- }
- }
- if(!turn_params.no_dtls && (turn_params.no_udp || (turn_params.listener_port != turn_params.tls_listener_port))) {
- barrier_count += turn_params.listener.addrs_number;
- if(turn_params.rfc5780) {
- barrier_count += turn_params.listener.addrs_number;
- }
- }
- if(!turn_params.no_udp || !turn_params.no_dtls) {
- barrier_count += (unsigned int)turn_params.aux_servers_list.size;
- }
- }
- #endif
- #if !defined(TURN_NO_THREAD_BARRIERS)
- {
- if(pthread_barrier_init(&barrier,NULL,barrier_count)<0)
- perror("barrier init");
- }
- #endif
- }
- static void setup_socket_per_endpoint_udp_listener_servers(void)
- {
- size_t i = 0;
- /* Adjust udp relay number */
- if(turn_params.general_relay_servers_number>1) {
- if (!turn_params.no_udp) {
- turn_params.udp_relay_servers_number += turn_params.listener.addrs_number;
- if (turn_params.rfc5780) {
- turn_params.udp_relay_servers_number += turn_params.listener.addrs_number;
- }
- }
- if (!turn_params.no_dtls && (turn_params.no_udp || (turn_params.listener_port != turn_params.tls_listener_port))) {
- turn_params.udp_relay_servers_number += turn_params.listener.addrs_number;
- if (turn_params.rfc5780) {
- turn_params.udp_relay_servers_number += turn_params.listener.addrs_number;
- }
- }
- if (!turn_params.no_udp || !turn_params.no_dtls) {
- turn_params.udp_relay_servers_number += (unsigned int) turn_params.aux_servers_list.size;
- }
- }
- {
- if (!turn_params.no_udp || !turn_params.no_dtls) {
- for (i = 0; i < get_real_udp_relay_servers_number(); i++) {
- ioa_engine_handle e = turn_params.listener.ioa_eng;
- int is_5780 = turn_params.rfc5780;
- if(turn_params.general_relay_servers_number<=1) {
- while(!(general_relay_servers[0]->ioa_eng))
- sched_yield();
- udp_relay_servers[i] = general_relay_servers[0];
- continue;
- } else if(turn_params.general_relay_servers_number>1) {
- e = create_new_listener_engine();
- is_5780 = is_5780 && (i >= (size_t) (turn_params.aux_servers_list.size));
- }
- super_memory_t *sm = new_super_memory_region();
- struct relay_server* udp_rs = (struct relay_server*) allocate_super_memory_region(sm, sizeof(struct relay_server));
- udp_rs->id = (turnserver_id) i + TURNSERVER_ID_BOUNDARY_BETWEEN_TCP_AND_UDP;
- udp_rs->sm = sm;
- setup_relay_server(udp_rs, e, is_5780);
- udp_relay_servers[i] = udp_rs;
- }
- }
- }
- int udp_relay_server_index = 0;
- /* Create listeners */
- /* Aux UDP servers */
- for(i=0; i<turn_params.aux_servers_list.size; i++) {
- int index = i;
- if(!turn_params.no_udp || !turn_params.no_dtls) {
- ioa_addr addr;
- char saddr[129];
- addr_cpy(&addr,&turn_params.aux_servers_list.addrs[i]);
- int port = (int)addr_get_port(&addr);
- addr_to_string_no_port(&addr,(uint8_t*)saddr);
- turn_params.listener.aux_udp_services[index] = (dtls_listener_relay_server_type**)allocate_super_memory_engine(udp_relay_servers[udp_relay_server_index]->ioa_eng, sizeof(dtls_listener_relay_server_type*));
- turn_params.listener.aux_udp_services[index][0] = create_dtls_listener_server(turn_params.listener_ifname, saddr, port, turn_params.verbose, udp_relay_servers[udp_relay_server_index]->ioa_eng, &(udp_relay_servers[udp_relay_server_index]->server), 1, NULL);
- if(turn_params.general_relay_servers_number>1) {
- ++udp_relay_server_index;
- pthread_t thr;
- if(pthread_create(&thr, NULL, run_udp_listener_thread, turn_params.listener.aux_udp_services[index][0])) {
- perror("Cannot create aux listener thread\n");
- exit(-1);
- }
- pthread_detach(thr);
- }
- }
- }
- /* Main servers */
- for(i=0; i<turn_params.listener.addrs_number; i++) {
- int index = turn_params.rfc5780 ? i*2 : i;
- /* UDP: */
- if(!turn_params.no_udp) {
- turn_params.listener.udp_services[index] = (dtls_listener_relay_server_type**)allocate_super_memory_engine(udp_relay_servers[udp_relay_server_index]->ioa_eng, sizeof(dtls_listener_relay_server_type*));
- turn_params.listener.udp_services[index][0] = create_dtls_listener_server(turn_params.listener_ifname, turn_params.listener.addrs[i], turn_params.listener_port, turn_params.verbose, udp_relay_servers[udp_relay_server_index]->ioa_eng, &(udp_relay_servers[udp_relay_server_index]->server), 1, NULL);
- if(turn_params.general_relay_servers_number>1) {
- ++udp_relay_server_index;
- pthread_t thr;
- if(pthread_create(&thr, NULL, run_udp_listener_thread, turn_params.listener.udp_services[index][0])) {
- perror("Cannot create listener thread\n");
- exit(-1);
- }
- pthread_detach(thr);
- }
- if(turn_params.rfc5780) {
- turn_params.listener.udp_services[index+1] = (dtls_listener_relay_server_type**)allocate_super_memory_engine(udp_relay_servers[udp_relay_server_index]->ioa_eng, sizeof(dtls_listener_relay_server_type*));
- turn_params.listener.udp_services[index+1][0] = create_dtls_listener_server(turn_params.listener_ifname, turn_params.listener.addrs[i], get_alt_listener_port(), turn_params.verbose, udp_relay_servers[udp_relay_server_index]->ioa_eng, &(udp_relay_servers[udp_relay_server_index]->server), 1, NULL);
- if(turn_params.general_relay_servers_number>1) {
- ++udp_relay_server_index;
- pthread_t thr;
- if(pthread_create(&thr, NULL, run_udp_listener_thread, turn_params.listener.udp_services[index+1][0])) {
- perror("Cannot create listener thread\n");
- exit(-1);
- }
- pthread_detach(thr);
- }
- }
- } else {
- turn_params.listener.udp_services[index] = NULL;
- if(turn_params.rfc5780)
- turn_params.listener.udp_services[index+1] = NULL;
- }
- if(!turn_params.no_dtls && (turn_params.no_udp || (turn_params.listener_port != turn_params.tls_listener_port))) {
- turn_params.listener.dtls_services[index] = (dtls_listener_relay_server_type**)allocate_super_memory_engine(udp_relay_servers[udp_relay_server_index]->ioa_eng, sizeof(dtls_listener_relay_server_type*));
- turn_params.listener.dtls_services[index][0] = create_dtls_listener_server(turn_params.listener_ifname, turn_params.listener.addrs[i], turn_params.tls_listener_port, turn_params.verbose, udp_relay_servers[udp_relay_server_index]->ioa_eng, &(udp_relay_servers[udp_relay_server_index]->server), 1, NULL);
- if(turn_params.general_relay_servers_number>1) {
- ++udp_relay_server_index;
- pthread_t thr;
- if(pthread_create(&thr, NULL, run_udp_listener_thread, turn_params.listener.dtls_services[index][0])) {
- perror("Cannot create listener thread\n");
- exit(-1);
- }
- pthread_detach(thr);
- }
- if(turn_params.rfc5780) {
- turn_params.listener.dtls_services[index+1] = (dtls_listener_relay_server_type**)allocate_super_memory_engine(udp_relay_servers[udp_relay_server_index]->ioa_eng, sizeof(dtls_listener_relay_server_type*));
- turn_params.listener.dtls_services[index+1][0] = create_dtls_listener_server(turn_params.listener_ifname, turn_params.listener.addrs[i], get_alt_tls_listener_port(), turn_params.verbose, udp_relay_servers[udp_relay_server_index]->ioa_eng, &(udp_relay_servers[udp_relay_server_index]->server), 1, NULL);
- if(turn_params.general_relay_servers_number>1) {
- ++udp_relay_server_index;
- pthread_t thr;
- if(pthread_create(&thr, NULL, run_udp_listener_thread, turn_params.listener.dtls_services[index+1][0])) {
- perror("Cannot create listener thread\n");
- exit(-1);
- }
- pthread_detach(thr);
- }
- }
- } else {
- turn_params.listener.dtls_services[index] = NULL;
- if(turn_params.rfc5780)
- turn_params.listener.dtls_services[index+1] = NULL;
- }
- }
- }
- static void setup_socket_per_thread_udp_listener_servers(void)
- {
- size_t i = 0;
- size_t relayindex = 0;
- /* Create listeners */
- for(relayindex=0;relayindex<get_real_general_relay_servers_number();relayindex++) {
- while(!(general_relay_servers[relayindex]->ioa_eng) || !(general_relay_servers[relayindex]->server.e))
- sched_yield();
- }
- /* Aux UDP servers */
- for(i=0; i<turn_params.aux_servers_list.size; i++) {
- int index = i;
- if(!turn_params.no_udp || !turn_params.no_dtls) {
- ioa_addr addr;
- char saddr[129];
- addr_cpy(&addr,&turn_params.aux_servers_list.addrs[i]);
- int port = (int)addr_get_port(&addr);
- addr_to_string_no_port(&addr,(uint8_t*)saddr);
- turn_params.listener.aux_udp_services[index] = (dtls_listener_relay_server_type**)allocate_super_memory_engine(turn_params.listener.ioa_eng, sizeof(dtls_listener_relay_server_type*) * get_real_general_relay_servers_number());
- for(relayindex=0;relayindex<get_real_general_relay_servers_number();relayindex++) {
- turn_params.listener.aux_udp_services[index][relayindex] = create_dtls_listener_server(turn_params.listener_ifname, saddr, port, turn_params.verbose,
- general_relay_servers[relayindex]->ioa_eng, &(general_relay_servers[relayindex]->server), !relayindex, NULL);
- }
- }
- }
- /* Main servers */
- for(i=0; i<turn_params.listener.addrs_number; i++) {
- int index = turn_params.rfc5780 ? i*2 : i;
- /* UDP: */
- if(!turn_params.no_udp) {
- turn_params.listener.udp_services[index] = (dtls_listener_relay_server_type**)allocate_super_memory_engine(turn_params.listener.ioa_eng, sizeof(dtls_listener_relay_server_type*) * get_real_general_relay_servers_number());
- for(relayindex=0;relayindex<get_real_general_relay_servers_number();relayindex++) {
- turn_params.listener.udp_services[index][relayindex] = create_dtls_listener_server(turn_params.listener_ifname, turn_params.listener.addrs[i], turn_params.listener_port, turn_params.verbose,
- general_relay_servers[relayindex]->ioa_eng, &(general_relay_servers[relayindex]->server), !relayindex, NULL);
- }
- if(turn_params.rfc5780) {
- turn_params.listener.udp_services[index+1] = (dtls_listener_relay_server_type**)allocate_super_memory_engine(turn_params.listener.ioa_eng, sizeof(dtls_listener_relay_server_type*) * get_real_general_relay_servers_number());
- for(relayindex=0;relayindex<get_real_general_relay_servers_number();relayindex++) {
- turn_params.listener.udp_services[index+1][relayindex] = create_dtls_listener_server(turn_params.listener_ifname, turn_params.listener.addrs[i], get_alt_listener_port(), turn_params.verbose,
- general_relay_servers[relayindex]->ioa_eng, &(general_relay_servers[relayindex]->server), !relayindex, NULL);
- }
- }
- } else {
- turn_params.listener.udp_services[index] = NULL;
- if(turn_params.rfc5780)
- turn_params.listener.udp_services[index+1] = NULL;
- }
- if(!turn_params.no_dtls && (turn_params.no_udp || (turn_params.listener_port != turn_params.tls_listener_port))) {
- turn_params.listener.dtls_services[index] = (dtls_listener_relay_server_type**)allocate_super_memory_engine(turn_params.listener.ioa_eng, sizeof(dtls_listener_relay_server_type*) * get_real_general_relay_servers_number());
- for(relayindex=0;relayindex<get_real_general_relay_servers_number();relayindex++) {
- turn_params.listener.dtls_services[index][relayindex] = create_dtls_listener_server(turn_params.listener_ifname, turn_params.listener.addrs[i], turn_params.tls_listener_port, turn_params.verbose,
- general_relay_servers[relayindex]->ioa_eng, &(general_relay_servers[relayindex]->server), !relayindex, NULL);
- }
- if(turn_params.rfc5780) {
- turn_params.listener.dtls_services[index+1] = (dtls_listener_relay_server_type**)allocate_super_memory_engine(turn_params.listener.ioa_eng, sizeof(dtls_listener_relay_server_type*) * get_real_general_relay_servers_number());
- for(relayindex=0;relayindex<get_real_general_relay_servers_number();relayindex++) {
- turn_params.listener.dtls_services[index+1][relayindex] = create_dtls_listener_server(turn_params.listener_ifname, turn_params.listener.addrs[i], get_alt_tls_listener_port(), turn_params.verbose,
- general_relay_servers[relayindex]->ioa_eng, &(general_relay_servers[relayindex]->server), !relayindex, NULL);
- }
- }
- } else {
- turn_params.listener.dtls_services[index] = NULL;
- if(turn_params.rfc5780)
- turn_params.listener.dtls_services[index+1] = NULL;
- }
- }
- }
- static void setup_socket_per_session_udp_listener_servers(void)
- {
- size_t i = 0;
- /* Aux UDP servers */
- for(i=0; i<turn_params.aux_servers_list.size; i++) {
- int index = i;
- if(!turn_params.no_udp || !turn_params.no_dtls) {
- ioa_addr addr;
- char saddr[129];
- addr_cpy(&addr,&turn_params.aux_servers_list.addrs[i]);
- int port = (int)addr_get_port(&addr);
- addr_to_string_no_port(&addr,(uint8_t*)saddr);
- turn_params.listener.aux_udp_services[index] = (dtls_listener_relay_server_type**)allocate_super_memory_engine(turn_params.listener.ioa_eng, sizeof(dtls_listener_relay_server_type*));
- turn_params.listener.aux_udp_services[index][0] = create_dtls_listener_server(turn_params.listener_ifname, saddr, port, turn_params.verbose,
- turn_params.listener.ioa_eng, NULL, 1, send_socket_to_general_relay);
- }
- }
- /* Main servers */
- for(i=0; i<turn_params.listener.addrs_number; i++) {
- int index = turn_params.rfc5780 ? i*2 : i;
- /* UDP: */
- if(!turn_params.no_udp) {
- turn_params.listener.udp_services[index] = (dtls_listener_relay_server_type**)allocate_super_memory_engine(turn_params.listener.ioa_eng, sizeof(dtls_listener_relay_server_type*));
- turn_params.listener.udp_services[index][0] = create_dtls_listener_server(turn_params.listener_ifname, turn_params.listener.addrs[i], turn_params.listener_port, turn_params.verbose,
- turn_params.listener.ioa_eng, NULL, 1, send_socket_to_general_relay);
- if(turn_params.rfc5780) {
- turn_params.listener.udp_services[index+1] = (dtls_listener_relay_server_type**)allocate_super_memory_engine(turn_params.listener.ioa_eng, sizeof(dtls_listener_relay_server_type*));
- turn_params.listener.udp_services[index+1][0] = create_dtls_listener_server(turn_params.listener_ifname, turn_params.listener.addrs[i], get_alt_listener_port(), turn_params.verbose,
- turn_params.listener.ioa_eng, NULL, 1, send_socket_to_general_relay);
- }
- } else {
- turn_params.listener.udp_services[index] = NULL;
- if(turn_params.rfc5780)
- turn_params.listener.udp_services[index+1] = NULL;
- }
- if(!turn_params.no_dtls && (turn_params.no_udp || (turn_params.listener_port != turn_params.tls_listener_port))) {
- turn_params.listener.dtls_services[index] = (dtls_listener_relay_server_type**)allocate_super_memory_engine(turn_params.listener.ioa_eng, sizeof(dtls_listener_relay_server_type*));
- turn_params.listener.dtls_services[index][0] = create_dtls_listener_server(turn_params.listener_ifname, turn_params.listener.addrs[i], turn_params.tls_listener_port, turn_params.verbose,
- turn_params.listener.ioa_eng, NULL, 1, send_socket_to_general_relay);
- if(turn_params.rfc5780) {
- turn_params.listener.dtls_services[index+1] = (dtls_listener_relay_server_type**)allocate_super_memory_engine(turn_params.listener.ioa_eng, sizeof(dtls_listener_relay_server_type*));
- turn_params.listener.dtls_services[index+1][0] = create_dtls_listener_server(turn_params.listener_ifname, turn_params.listener.addrs[i], get_alt_tls_listener_port(), turn_params.verbose,
- turn_params.listener.ioa_eng, NULL, 1, send_socket_to_general_relay);
- }
- } else {
- turn_params.listener.dtls_services[index] = NULL;
- if(turn_params.rfc5780)
- turn_params.listener.dtls_services[index+1] = NULL;
- }
- }
- }
- static void setup_tcp_listener_servers(ioa_engine_handle e, struct relay_server *relay_server)
- {
- size_t i = 0;
- tls_listener_relay_server_type **tcp_services = (tls_listener_relay_server_type**)allocate_super_memory_engine(turn_params.listener.ioa_eng, sizeof(tls_listener_relay_server_type*)*turn_params.listener.services_number);
- tls_listener_relay_server_type **tls_services = (tls_listener_relay_server_type**)allocate_super_memory_engine(turn_params.listener.ioa_eng, sizeof(tls_listener_relay_server_type*)*turn_params.listener.services_number);
- tls_listener_relay_server_type **aux_tcp_services = (tls_listener_relay_server_type**)allocate_super_memory_engine(turn_params.listener.ioa_eng, sizeof(tls_listener_relay_server_type*)*turn_params.aux_servers_list.size+1);
- /* Create listeners */
- /* Aux TCP servers */
- 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++) {
- ioa_addr addr;
- char saddr[129];
- addr_cpy(&addr,&turn_params.aux_servers_list.addrs[i]);
- int port = (int)addr_get_port(&addr);
- addr_to_string_no_port(&addr,(uint8_t*)saddr);
- aux_tcp_services[i] = create_tls_listener_server(turn_params.listener_ifname, saddr, port, turn_params.verbose, e, send_socket_to_general_relay, relay_server);
- }
- }
- /* Main servers */
- for(i=0; i<turn_params.listener.addrs_number; i++) {
- int index = turn_params.rfc5780 ? i*2 : i;
- /* TCP: */
- if(!turn_params.no_tcp) {
- 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] = 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.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);
- } else {
- tls_services[index] = NULL;
- if(turn_params.rfc5780)
- tls_services[index+1] = NULL;
- }
- }
- }
- static int get_alt_addr(ioa_addr *addr, ioa_addr *alt_addr)
- {
- if(!addr || !turn_params.rfc5780 || (turn_params.listener.addrs_number<2))
- ;
- else {
- size_t index = 0xffff;
- size_t i = 0;
- int alt_port = -1;
- int port = addr_get_port(addr);
- if(port == turn_params.listener_port)
- alt_port = get_alt_listener_port();
- else if(port == get_alt_listener_port())
- alt_port = turn_params.listener_port;
- else if(port == turn_params.tls_listener_port)
- alt_port = get_alt_tls_listener_port();
- else if(port == get_alt_tls_listener_port())
- alt_port = turn_params.tls_listener_port;
- else
- return -1;
- for(i=0;i<turn_params.listener.addrs_number;i++) {
- if(turn_params.listener.encaddrs && turn_params.listener.encaddrs[i]) {
- if(addr->ss.sa_family == turn_params.listener.encaddrs[i]->ss.sa_family) {
- index=i;
- break;
- }
- }
- }
- if(index!=0xffff) {
- for(i=0;i<turn_params.listener.addrs_number;i++) {
- size_t ind = (index+i+1) % turn_params.listener.addrs_number;
- if(turn_params.listener.encaddrs && turn_params.listener.encaddrs[ind]) {
- ioa_addr *caddr = turn_params.listener.encaddrs[ind];
- if(caddr->ss.sa_family == addr->ss.sa_family) {
- addr_cpy(alt_addr,caddr);
- addr_set_port(alt_addr, alt_port);
- return 0;
- }
- }
- }
- }
- }
- return -1;
- }
- static void run_events(struct event_base *eb, ioa_engine_handle e)
- {
- if(!eb && e)
- eb = e->event_base;
- if (!eb)
- return;
- struct timeval timeout;
- timeout.tv_sec = 5;
- timeout.tv_usec = 0;
- event_base_loopexit(eb, &timeout);
- event_base_dispatch(eb);
- #if !defined(TURN_NO_HIREDIS)
- if(e)
- send_message_to_redis(e->rch, "publish", "__XXX__", "__YYY__");
- #endif
- }
- void run_listener_server(struct listener_server *ls)
- {
- unsigned int cycle = 0;
- while (!turn_params.stop_turn_server) {
- #if !defined(TURN_NO_SYSTEMD)
- sd_notify (0, "READY=1");
- #endif
- if (eve(turn_params.verbose)) {
- if ((cycle++ & 15) == 0) {
- TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: cycle=%u\n", __FUNCTION__, cycle);
- }
- }
- run_events(ls->event_base, ls->ioa_eng);
- rollover_logfile();
- }
- #if !defined(TURN_NO_SYSTEMD)
- sd_notify (0, "STOPPING=1");
- #endif
- }
- static void setup_relay_server(struct relay_server *rs, ioa_engine_handle e, int to_set_rfc5780)
- {
- struct bufferevent *pair[2];
- if(e) {
- rs->event_base = e->event_base;
- rs->ioa_eng = e;
- } else {
- rs->event_base = turn_event_base_new();
- TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"IO method (general relay thread): %s\n",event_base_get_method(rs->event_base));
- rs->ioa_eng = create_ioa_engine(rs->sm, rs->event_base, turn_params.listener.tp, turn_params.relay_ifname,
- turn_params.relays_number, turn_params.relay_addrs, turn_params.default_relays, turn_params.verbose
- #if !defined(TURN_NO_HIREDIS)
- ,turn_params.redis_statsdb
- #endif
- );
- set_ssl_ctx(rs->ioa_eng, &turn_params);
- ioa_engine_set_rtcp_map(rs->ioa_eng, turn_params.listener.rtcpmap);
- }
- bufferevent_pair_new(rs->event_base, TURN_BUFFEREVENTS_OPTIONS, pair);
- rs->in_buf = pair[0];
- rs->out_buf = pair[1];
- bufferevent_setcb(rs->in_buf, relay_receive_message, NULL, NULL, rs);
- bufferevent_enable(rs->in_buf, EV_READ);
- bufferevent_pair_new(rs->event_base, TURN_BUFFEREVENTS_OPTIONS, pair);
- rs->auth_in_buf = pair[0];
- rs->auth_out_buf = pair[1];
- bufferevent_setcb(rs->auth_in_buf, relay_receive_auth_message, NULL, NULL, rs);
- bufferevent_enable(rs->auth_in_buf, EV_READ);
- init_turn_server(&(rs->server),
- rs->id, turn_params.verbose,
- rs->ioa_eng, turn_params.ct, 0,
- turn_params.fingerprint, DONT_FRAGMENT_SUPPORTED,
- start_user_check,
- check_new_allocation_quota,
- release_allocation_quota,
- turn_params.external_ip,
- &turn_params.check_origin,
- &turn_params.no_tcp_relay,
- &turn_params.no_udp_relay,
- &turn_params.stale_nonce,
- &turn_params.max_allocate_lifetime,
- &turn_params.channel_lifetime,
- &turn_params.permission_lifetime,
- &turn_params.stun_only,
- &turn_params.no_stun,
- &turn_params.no_software_attribute,
- &turn_params.web_admin_listen_on_workers,
- &turn_params.alternate_servers_list,
- &turn_params.tls_alternate_servers_list,
- &turn_params.aux_servers_list,
- turn_params.udp_self_balance,
- &turn_params.no_multicast_peers, &turn_params.allow_loopback_peers,
- &turn_params.ip_whitelist, &turn_params.ip_blacklist,
- send_socket_to_relay,
- &turn_params.secure_stun, &turn_params.mobility,
- turn_params.server_relay,
- send_turn_session_info,
- send_https_socket,
- allocate_bps,
- turn_params.oauth,
- turn_params.oauth_server_name,
- turn_params.acme_redirect,
- turn_params.allocation_default_address_family,
- &turn_params.log_binding,
- &turn_params.no_stun_backward_compatibility,
- &turn_params.response_origin_only_with_rfc5780
- );
-
- if(to_set_rfc5780) {
- set_rfc5780(&(rs->server), get_alt_addr, send_message_from_listener_to_client);
- }
- if(turn_params.net_engine_version == NEV_UDP_SOCKET_PER_THREAD) {
- setup_tcp_listener_servers(rs->ioa_eng, rs);
- }
- }
- static void *run_general_relay_thread(void *arg)
- {
- static int always_true = 1;
- struct relay_server *rs = (struct relay_server *)arg;
-
- int udp_reuses_the_same_relay_server = (turn_params.general_relay_servers_number<=1) || (turn_params.net_engine_version == NEV_UDP_SOCKET_PER_THREAD) || (turn_params.net_engine_version == NEV_UDP_SOCKET_PER_SESSION);
- int we_need_rfc5780 = udp_reuses_the_same_relay_server && turn_params.rfc5780;
- ignore_sigpipe();
- setup_relay_server(rs, NULL, we_need_rfc5780);
- barrier_wait();
- while(always_true) {
- run_events(rs->event_base, rs->ioa_eng);
- }
-
- return arg;
- }
- static void setup_general_relay_servers(void)
- {
- size_t i = 0;
- for(i=0;i<get_real_general_relay_servers_number();i++) {
- if(turn_params.general_relay_servers_number == 0) {
- general_relay_servers[i] = (struct relay_server*)allocate_super_memory_engine(turn_params.listener.ioa_eng, sizeof(struct relay_server));
- general_relay_servers[i]->id = (turnserver_id)i;
- general_relay_servers[i]->sm = NULL;
- setup_relay_server(general_relay_servers[i], turn_params.listener.ioa_eng, ((turn_params.net_engine_version == NEV_UDP_SOCKET_PER_THREAD) || (turn_params.net_engine_version == NEV_UDP_SOCKET_PER_SESSION)) && turn_params.rfc5780);
- general_relay_servers[i]->thr = pthread_self();
- } else {
- super_memory_t *sm = new_super_memory_region();
- general_relay_servers[i] = (struct relay_server*)allocate_super_memory_region(sm,sizeof(struct relay_server));
- general_relay_servers[i]->id = (turnserver_id)i;
- general_relay_servers[i]->sm = sm;
- if(pthread_create(&(general_relay_servers[i]->thr), NULL, run_general_relay_thread, general_relay_servers[i])) {
- perror("Cannot create relay thread\n");
- exit(-1);
- }
- pthread_detach(general_relay_servers[i]->thr);
- }
- }
- }
- static int run_auth_server_flag = 1;
- static void* run_auth_server_thread(void *arg)
- {
- ignore_sigpipe();
- struct auth_server *as = (struct auth_server*)arg;
- authserver_id id = as->id;
- if(id == 0) {
- reread_realms();
- update_white_and_black_lists();
- barrier_wait();
- while(run_auth_server_flag) {
- #if defined(DB_TEST)
- run_db_test();
- #endif
- sleep(5);
- reread_realms();
- update_white_and_black_lists();
- }
- } else {
- bzero(as,sizeof(struct auth_server));
- as->id = id;
- as->event_base = turn_event_base_new();
- TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"IO method (auth thread): %s\n",event_base_get_method(as->event_base));
- struct bufferevent *pair[2];
- bufferevent_pair_new(as->event_base, TURN_BUFFEREVENTS_OPTIONS, pair);
- as->in_buf = pair[0];
- as->out_buf = pair[1];
- bufferevent_setcb(as->in_buf, auth_server_receive_message, NULL, NULL, as);
- bufferevent_enable(as->in_buf, EV_READ);
- #if !defined(TURN_NO_HIREDIS)
- as->rch = get_redis_async_connection(as->event_base, turn_params.redis_statsdb, 1);
- #endif
- barrier_wait();
- while(run_auth_server_flag) {
- if (!turn_params.no_auth_pings) {
- auth_ping(as->rch);
- }
- run_events(as->event_base,NULL);
- }
- }
- return arg;
- }
- static void setup_auth_server(struct auth_server *as)
- {
- pthread_attr_t attr;
- if(pthread_attr_init(&attr) ||
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) ||
- pthread_create(&(as->thr), &attr, run_auth_server_thread, as)) {
- perror("Cannot create auth thread\n");
- exit(-1);
- }
- }
- static void* run_admin_server_thread(void *arg)
- {
- ignore_sigpipe();
- setup_admin_thread();
- barrier_wait();
- while(adminserver.event_base) {
- run_events(adminserver.event_base,NULL);
- }
- return arg;
- }
- static void setup_admin_server(void)
- {
- bzero(&adminserver,sizeof(struct admin_server));
- adminserver.listen_fd = -1;
- adminserver.verbose = turn_params.verbose;
- if(pthread_create(&(adminserver.thr), NULL, run_admin_server_thread, &adminserver)) {
- perror("Cannot create cli thread\n");
- exit(-1);
- }
- pthread_detach(adminserver.thr);
- }
- void setup_server(void)
- {
- evthread_use_pthreads();
- pthread_mutex_init(&mutex_bps, NULL);
- authserver_number = 1 + (authserver_id)(turn_params.cpus / 2);
- if(authserver_number < MIN_AUTHSERVER_NUMBER) authserver_number = MIN_AUTHSERVER_NUMBER;
- #if !defined(TURN_NO_THREAD_BARRIERS)
- /* relay threads plus auth threads plus main listener thread */
- /* plus admin thread */
- /* udp address listener thread(s) will start later */
- barrier_count = turn_params.general_relay_servers_number+authserver_number+1+1;
- #endif
- setup_listener();
- allocate_relay_addrs_ports();
- setup_barriers();
- setup_general_relay_servers();
- if(turn_params.net_engine_version == NEV_UDP_SOCKET_PER_THREAD)
- setup_socket_per_thread_udp_listener_servers();
- else if(turn_params.net_engine_version == NEV_UDP_SOCKET_PER_ENDPOINT)
- setup_socket_per_endpoint_udp_listener_servers();
- else if(turn_params.net_engine_version == NEV_UDP_SOCKET_PER_SESSION)
- setup_socket_per_session_udp_listener_servers();
- if(turn_params.net_engine_version != NEV_UDP_SOCKET_PER_THREAD) {
- setup_tcp_listener_servers(turn_params.listener.ioa_eng, NULL);
- }
- {
- int tot = 0;
- if(udp_relay_servers[0]) {
- tot = get_real_udp_relay_servers_number();
- }
- if(tot) {
- TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,"Total UDP servers: %d\n",(int)tot);
- }
- }
- {
- int tot = get_real_general_relay_servers_number();
- 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);
- }
- }
- }
- }
- {
- authserver_id sn = 0;
- for(sn = 0; sn < authserver_number;++sn) {
- authserver[sn].id = sn;
- setup_auth_server(&(authserver[sn]));
- }
- }
- setup_admin_server();
- barrier_wait();
- }
- void init_listener(void)
- {
- bzero(&turn_params.listener,sizeof(struct listener_server));
- }
- ///////////////////////////////
|