Skip to content

Commit 3eddec2

Browse files
Merge pull request #920 from murillo128/master
Add PeerConnection::setConfiguration() method
2 parents f61fe88 + 0620dda commit 3eddec2

File tree

5 files changed

+137
-76
lines changed

5 files changed

+137
-76
lines changed

include/rtc/configuration.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ struct RTC_CPP_EXPORT Configuration {
7575
bool enableIceTcp = false; // libnice only
7676
bool enableIceUdpMux = false; // libjuice only
7777
bool disableAutoNegotiation = false;
78+
bool disableAutoGathering = false;
7879
bool forceMediaTransport = false;
7980

8081
// Port range

include/rtc/peerconnection.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ class RTC_CPP_EXPORT PeerConnection final : CheshireCat<impl::PeerConnection> {
9393
void setLocalDescription(Description::Type type = Description::Type::Unspec);
9494
void setRemoteDescription(Description description);
9595
void addRemoteCandidate(Candidate candidate);
96+
void gatherLocalCandidates(std::vector<IceServer> additionalIceServers = {});
9697

9798
void setMediaHandler(shared_ptr<MediaHandler> handler);
9899
shared_ptr<MediaHandler> getMediaHandler();

src/impl/icetransport.cpp

+117-74
Original file line numberDiff line numberDiff line change
@@ -117,27 +117,6 @@ IceTransport::IceTransport(const Configuration &config, candidate_callback candi
117117
}
118118
}
119119

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-
141120
// Bind address
142121
if (config.bindAddress) {
143122
jconfig.bind_address = config.bindAddress->c_str();
@@ -154,6 +133,44 @@ IceTransport::IceTransport(const Configuration &config, candidate_callback candi
154133
mAgent = decltype(mAgent)(juice_create(&jconfig), juice_destroy);
155134
if (!mAgent)
156135
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+
}
157174
}
158175

159176
IceTransport::~IceTransport() {
@@ -210,8 +227,17 @@ bool IceTransport::addRemoteCandidate(const Candidate &candidate) {
210227
return juice_add_remote_candidate(mAgent.get(), string(candidate).c_str()) >= 0;
211228
}
212229

213-
void IceTransport::gatherLocalCandidates(string mid) {
230+
void IceTransport::gatherLocalCandidates(string mid, std::vector<IceServer> additionalIceServers) {
214231
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+
}
215241

216242
// Change state now as candidates calls can be synchronous
217243
changeGatheringState(GatheringState::InProgress);
@@ -533,59 +559,17 @@ IceTransport::IceTransport(const Configuration &config, candidate_callback candi
533559
break;
534560
}
535561

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+
536570
// Add TURN servers
537571
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);
589573
}
590574

591575
g_signal_connect(G_OBJECT(mNiceAgent.get()), "component-state-changed",
@@ -603,6 +587,60 @@ IceTransport::IceTransport(const Configuration &config, candidate_callback candi
603587
RecvCallback, this);
604588
}
605589

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+
606644
IceTransport::~IceTransport() {
607645
PLOG_DEBUG << "Destroying ICE transport";
608646
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) {
684722
return ret > 0;
685723
}
686724

687-
void IceTransport::gatherLocalCandidates(string mid) {
725+
void IceTransport::gatherLocalCandidates(string mid, std::vector<IceServer> additionalIceServers) {
688726
mMid = std::move(mid);
727+
std::shuffle(additionalIceServers.begin(), additionalIceServers.end(), utils::random_engine());
728+
729+
for (auto &server : additionalIceServers) {
730+
addIceServer(server);
731+
}
689732

690733
// Change state now as candidates calls can be synchronous
691734
changeGatheringState(GatheringState::InProgress);

src/impl/icetransport.hpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class IceTransport : public Transport {
5050
Description getLocalDescription(Description::Type type) const;
5151
void setRemoteDescription(const Description &description);
5252
bool addRemoteCandidate(const Candidate &candidate);
53-
void gatherLocalCandidates(string mid);
53+
void gatherLocalCandidates(string mid, std::vector<IceServer> additionalIceServers = {});
5454

5555
optional<string> getLocalAddress() const;
5656
optional<string> getRemoteAddress() const;
@@ -69,6 +69,8 @@ class IceTransport : public Transport {
6969
void processGatheringDone();
7070
void processTimeout();
7171

72+
void addIceServer(IceServer server);
73+
7274
Description::Role mRole;
7375
string mMid;
7476
std::chrono::milliseconds mTrickleTimeout;
@@ -79,6 +81,7 @@ class IceTransport : public Transport {
7981

8082
#if !USE_NICE
8183
unique_ptr<juice_agent_t, void (*)(juice_agent_t *)> mAgent;
84+
int mTURNServersAdded = 0;
8285

8386
static void StateChangeCallback(juice_agent_t *agent, juice_state_t state, void *user_ptr);
8487
static void CandidateCallback(juice_agent_t *agent, const char *sdp, void *user_ptr);

src/peerconnection.cpp

+14-1
Original file line numberDiff line numberDiff line change
@@ -146,11 +146,24 @@ void PeerConnection::setLocalDescription(Description::Type type) {
146146
impl()->changeSignalingState(newSignalingState);
147147
signalingLock.unlock();
148148

149-
if (impl()->gatheringState == GatheringState::New) {
149+
if (impl()->gatheringState == GatheringState::New && !impl()->config.disableAutoGathering) {
150150
iceTransport->gatherLocalCandidates(impl()->localBundleMid());
151151
}
152152
}
153153

154+
void PeerConnection::gatherLocalCandidates(std::vector<IceServer> additionalIceServers) {
155+
auto iceTransport = impl()->getIceTransport();
156+
if (!iceTransport) {
157+
throw std::logic_error("No IceTransport. Local Description has not been set");
158+
}
159+
160+
if (impl()->gatheringState == GatheringState::New) {
161+
iceTransport->gatherLocalCandidates(impl()->localBundleMid(), additionalIceServers);
162+
} else {
163+
PLOG_WARNING << "Candidates gathering already started";
164+
}
165+
}
166+
154167
void PeerConnection::setRemoteDescription(Description description) {
155168
std::unique_lock signalingLock(impl()->signalingMutex);
156169
PLOG_VERBOSE << "Setting remote description: " << string(description);

0 commit comments

Comments
 (0)