@@ -117,27 +117,6 @@ IceTransport::IceTransport(const Configuration &config, candidate_callback candi
117
117
}
118
118
}
119
119
120
- juice_turn_server_t turn_servers[MAX_TURN_SERVERS_COUNT];
121
- std::memset (turn_servers, 0 , sizeof (turn_servers));
122
-
123
- // Add TURN servers
124
- int k = 0 ;
125
- for (auto &server : servers) {
126
- if (!server.hostname .empty () && server.type == IceServer::Type::Turn) {
127
- if (server.port == 0 )
128
- server.port = 3478 ; // TURN UDP port
129
- PLOG_INFO << " Using TURN server \" " << server.hostname << " :" << server.port << " \" " ;
130
- turn_servers[k].host = server.hostname .c_str ();
131
- turn_servers[k].username = server.username .c_str ();
132
- turn_servers[k].password = server.password .c_str ();
133
- turn_servers[k].port = server.port ;
134
- if (++k >= MAX_TURN_SERVERS_COUNT)
135
- break ;
136
- }
137
- }
138
- jconfig.turn_servers = k > 0 ? turn_servers : nullptr ;
139
- jconfig.turn_servers_count = k;
140
-
141
120
// Bind address
142
121
if (config.bindAddress ) {
143
122
jconfig.bind_address = config.bindAddress ->c_str ();
@@ -154,6 +133,44 @@ IceTransport::IceTransport(const Configuration &config, candidate_callback candi
154
133
mAgent = decltype (mAgent )(juice_create (&jconfig), juice_destroy);
155
134
if (!mAgent )
156
135
throw std::runtime_error (" Failed to create the ICE agent" );
136
+
137
+ // Filter STUN servers
138
+ servers.erase (std::remove_if (servers.begin (), servers.end (),
139
+ [](const IceServer &server) {
140
+ return server.hostname .empty () ||
141
+ server.type != IceServer::Type::Turn;
142
+ }),
143
+ servers.end ());
144
+
145
+ // Add TURN servers
146
+ for (auto &server : servers) {
147
+ if (mTURNServersAdded ++ >= MAX_TURN_SERVERS_COUNT) {
148
+ break ;
149
+ }
150
+
151
+ addIceServer (server);
152
+ }
153
+ }
154
+
155
+ void IceTransport::addIceServer (IceServer server) {
156
+ if (server.hostname .empty () || server.type != IceServer::Type::Turn) {
157
+ PLOG_WARNING << " Only TURN servers are supported as additional ICE servers" ;
158
+ return ;
159
+ }
160
+
161
+ if (server.port == 0 )
162
+ server.port = 3478 ; // TURN UDP port
163
+
164
+ PLOG_INFO << " Using TURN server \" " << server.hostname << " :" << server.port << " \" " ;
165
+ juice_turn_server_t turn_server = {};
166
+ turn_server.host = server.hostname .c_str ();
167
+ turn_server.username = server.username .c_str ();
168
+ turn_server.password = server.password .c_str ();
169
+ turn_server.port = server.port ;
170
+
171
+ if (juice_add_turn_server (mAgent .get (), &turn_server) != 0 ) {
172
+ throw std::runtime_error (" Failed to add TURN server" );
173
+ }
157
174
}
158
175
159
176
IceTransport::~IceTransport () {
@@ -210,8 +227,17 @@ bool IceTransport::addRemoteCandidate(const Candidate &candidate) {
210
227
return juice_add_remote_candidate (mAgent .get (), string (candidate).c_str ()) >= 0 ;
211
228
}
212
229
213
- void IceTransport::gatherLocalCandidates (string mid) {
230
+ void IceTransport::gatherLocalCandidates (string mid, std::vector<IceServer> additionalIceServers ) {
214
231
mMid = std::move (mid);
232
+ std::shuffle (additionalIceServers.begin (), additionalIceServers.end (), utils::random_engine ());
233
+
234
+ for (auto &server : additionalIceServers) {
235
+ if (mTURNServersAdded ++ >= MAX_TURN_SERVERS_COUNT) {
236
+ break ;
237
+ }
238
+
239
+ addIceServer (server);
240
+ }
215
241
216
242
// Change state now as candidates calls can be synchronous
217
243
changeGatheringState (GatheringState::InProgress);
@@ -533,59 +559,17 @@ IceTransport::IceTransport(const Configuration &config, candidate_callback candi
533
559
break ;
534
560
}
535
561
562
+ // Filter STUN servers
563
+ servers.erase (std::remove_if (servers.begin (), servers.end (),
564
+ [](const IceServer &server) {
565
+ return server.hostname .empty () ||
566
+ server.type != IceServer::Type::Turn;
567
+ }),
568
+ servers.end ());
569
+
536
570
// Add TURN servers
537
571
for (auto &server : servers) {
538
- if (server.hostname .empty ())
539
- continue ;
540
- if (server.type != IceServer::Type::Turn)
541
- continue ;
542
- if (server.port == 0 )
543
- server.port = server.relayType == IceServer::RelayType::TurnTls ? 5349 : 3478 ;
544
-
545
- struct addrinfo hints = {};
546
- hints.ai_family = AF_UNSPEC;
547
- hints.ai_socktype =
548
- server.relayType == IceServer::RelayType::TurnUdp ? SOCK_DGRAM : SOCK_STREAM;
549
- hints.ai_protocol =
550
- server.relayType == IceServer::RelayType::TurnUdp ? IPPROTO_UDP : IPPROTO_TCP;
551
- hints.ai_flags = AI_ADDRCONFIG;
552
- struct addrinfo *result = nullptr ;
553
- if (getaddrinfo (server.hostname .c_str (), std::to_string (server.port ).c_str (), &hints,
554
- &result) != 0 ) {
555
- PLOG_WARNING << " Unable to resolve TURN server address: " << server.hostname << ' :'
556
- << server.port ;
557
- continue ;
558
- }
559
-
560
- for (auto p = result; p; p = p->ai_next ) {
561
- if (p->ai_family == AF_INET || p->ai_family == AF_INET6) {
562
- char nodebuffer[MAX_NUMERICNODE_LEN];
563
- char servbuffer[MAX_NUMERICSERV_LEN];
564
- if (getnameinfo (p->ai_addr , p->ai_addrlen , nodebuffer, MAX_NUMERICNODE_LEN,
565
- servbuffer, MAX_NUMERICSERV_LEN,
566
- NI_NUMERICHOST | NI_NUMERICSERV) == 0 ) {
567
- PLOG_INFO << " Using TURN server \" " << server.hostname << " :" << server.port
568
- << " \" " ;
569
- NiceRelayType niceRelayType;
570
- switch (server.relayType ) {
571
- case IceServer::RelayType::TurnTcp:
572
- niceRelayType = NICE_RELAY_TYPE_TURN_TCP;
573
- break ;
574
- case IceServer::RelayType::TurnTls:
575
- niceRelayType = NICE_RELAY_TYPE_TURN_TLS;
576
- break ;
577
- default :
578
- niceRelayType = NICE_RELAY_TYPE_TURN_UDP;
579
- break ;
580
- }
581
- nice_agent_set_relay_info (mNiceAgent .get (), mStreamId , 1 , nodebuffer,
582
- std::stoul (servbuffer), server.username .c_str (),
583
- server.password .c_str (), niceRelayType);
584
- }
585
- }
586
- }
587
-
588
- freeaddrinfo (result);
572
+ addIceServer (server);
589
573
}
590
574
591
575
g_signal_connect (G_OBJECT (mNiceAgent .get ()), " component-state-changed" ,
@@ -603,6 +587,60 @@ IceTransport::IceTransport(const Configuration &config, candidate_callback candi
603
587
RecvCallback, this );
604
588
}
605
589
590
+ void IceTransport::addIceServer (IceServer server) {
591
+ if (server.hostname .empty () || server.type != IceServer::Type::Turn) {
592
+ PLOG_WARNING << " Only TURN servers are supported as additional ICE servers" ;
593
+ return ;
594
+ }
595
+
596
+ if (server.port == 0 )
597
+ server.port = server.relayType == IceServer::RelayType::TurnTls ? 5349 : 3478 ;
598
+
599
+ struct addrinfo hints = {};
600
+ hints.ai_family = AF_UNSPEC;
601
+ hints.ai_socktype =
602
+ server.relayType == IceServer::RelayType::TurnUdp ? SOCK_DGRAM : SOCK_STREAM;
603
+ hints.ai_protocol =
604
+ server.relayType == IceServer::RelayType::TurnUdp ? IPPROTO_UDP : IPPROTO_TCP;
605
+ hints.ai_flags = AI_ADDRCONFIG;
606
+ struct addrinfo *result = nullptr ;
607
+ if (getaddrinfo (server.hostname .c_str (), std::to_string (server.port ).c_str (), &hints,
608
+ &result) != 0 ) {
609
+ PLOG_WARNING << " Unable to resolve TURN server address: " << server.hostname << ' :'
610
+ << server.port ;
611
+ return ;
612
+ }
613
+
614
+ for (auto p = result; p; p = p->ai_next ) {
615
+ if (p->ai_family == AF_INET || p->ai_family == AF_INET6) {
616
+ char nodebuffer[MAX_NUMERICNODE_LEN];
617
+ char servbuffer[MAX_NUMERICSERV_LEN];
618
+ if (getnameinfo (p->ai_addr , p->ai_addrlen , nodebuffer, MAX_NUMERICNODE_LEN, servbuffer,
619
+ MAX_NUMERICSERV_LEN, NI_NUMERICHOST | NI_NUMERICSERV) == 0 ) {
620
+ PLOG_INFO << " Using TURN server \" " << server.hostname << " :" << server.port
621
+ << " \" " ;
622
+ NiceRelayType niceRelayType;
623
+ switch (server.relayType ) {
624
+ case IceServer::RelayType::TurnTcp:
625
+ niceRelayType = NICE_RELAY_TYPE_TURN_TCP;
626
+ break ;
627
+ case IceServer::RelayType::TurnTls:
628
+ niceRelayType = NICE_RELAY_TYPE_TURN_TLS;
629
+ break ;
630
+ default :
631
+ niceRelayType = NICE_RELAY_TYPE_TURN_UDP;
632
+ break ;
633
+ }
634
+ nice_agent_set_relay_info (mNiceAgent .get (), mStreamId , 1 , nodebuffer,
635
+ std::stoul (servbuffer), server.username .c_str (),
636
+ server.password .c_str (), niceRelayType);
637
+ }
638
+ }
639
+ }
640
+
641
+ freeaddrinfo (result);
642
+ }
643
+
606
644
IceTransport::~IceTransport () {
607
645
PLOG_DEBUG << " Destroying ICE transport" ;
608
646
nice_agent_attach_recv (mNiceAgent .get (), mStreamId , 1 , g_main_loop_get_context (MainLoop.get ()),
@@ -684,8 +722,13 @@ bool IceTransport::addRemoteCandidate(const Candidate &candidate) {
684
722
return ret > 0 ;
685
723
}
686
724
687
- void IceTransport::gatherLocalCandidates (string mid) {
725
+ void IceTransport::gatherLocalCandidates (string mid, std::vector<IceServer> additionalIceServers ) {
688
726
mMid = std::move (mid);
727
+ std::shuffle (additionalIceServers.begin (), additionalIceServers.end (), utils::random_engine ());
728
+
729
+ for (auto &server : additionalIceServers) {
730
+ addIceServer (server);
731
+ }
689
732
690
733
// Change state now as candidates calls can be synchronous
691
734
changeGatheringState (GatheringState::InProgress);
0 commit comments