Skip to content

Commit edc5561

Browse files
murillo128Sean-Der
authored andcommitted
Add PeerConnection::setConfiguration() method
dedup TURN servers and only allow setConfiguration to change iceServers
1 parent fbd8f23 commit edc5561

9 files changed

+212
-124
lines changed

include/rtc/configuration.hpp

+23
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ struct RTC_CPP_EXPORT IceServer {
3838
string username;
3939
string password;
4040
RelayType relayType;
41+
42+
bool operator==(const IceServer &other) const {
43+
return other.hostname == hostname && other.port == port && other.type == type &&
44+
other.username == username && other.password == password &&
45+
other.relayType == relayType;
46+
}
4147
};
4248

4349
struct RTC_CPP_EXPORT ProxyServer {
@@ -53,6 +59,11 @@ struct RTC_CPP_EXPORT ProxyServer {
5359
uint16_t port;
5460
optional<string> username;
5561
optional<string> password;
62+
63+
bool operator==(const ProxyServer &other) const {
64+
return other.hostname == hostname && other.port == port && other.type == type &&
65+
other.username == username && other.password == password;
66+
}
5667
};
5768

5869
enum class CertificateType {
@@ -86,6 +97,18 @@ struct RTC_CPP_EXPORT Configuration {
8697

8798
// Local maximum message size for Data Channels
8899
optional<size_t> maxMessageSize;
100+
101+
bool equalsIgnoreIceServers(const Configuration &other) const {
102+
return other.proxyServer == proxyServer && other.bindAddress == bindAddress &&
103+
other.certificateType == certificateType &&
104+
other.iceTransportPolicy == iceTransportPolicy &&
105+
other.enableIceTcp == enableIceTcp && other.enableIceUdpMux == enableIceUdpMux &&
106+
other.enableIceUdpMux == enableIceUdpMux &&
107+
other.disableAutoNegotiation == disableAutoNegotiation &&
108+
other.forceMediaTransport == forceMediaTransport &&
109+
other.portRangeBegin == portRangeEnd && other.mtu == mtu &&
110+
other.maxMessageSize == maxMessageSize;
111+
}
89112
};
90113

91114
#ifdef RTC_ENABLE_WEBSOCKET

include/rtc/peerconnection.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class RTC_CPP_EXPORT PeerConnection final : CheshireCat<impl::PeerConnection> {
7777
void close();
7878

7979
const Configuration *config() const;
80+
void setConfiguration(const Configuration& config);
8081
State state() const;
8182
IceState iceState() const;
8283
GatheringState gatheringState() const;

include/rtc/rtc.h

+2
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,8 @@ RTC_C_EXPORT int rtcCreatePeerConnection(const rtcConfiguration *config); // ret
203203
RTC_C_EXPORT int rtcClosePeerConnection(int pc);
204204
RTC_C_EXPORT int rtcDeletePeerConnection(int pc);
205205

206+
RTC_C_EXPORT int rtcSetConfiguration(int pc, const rtcConfiguration *config);
207+
206208
RTC_C_EXPORT int rtcSetLocalDescriptionCallback(int pc, rtcDescriptionCallbackFunc cb);
207209
RTC_C_EXPORT int rtcSetLocalCandidateCallback(int pc, rtcCandidateCallbackFunc cb);
208210
RTC_C_EXPORT int rtcSetStateChangeCallback(int pc, rtcStateChangeCallbackFunc cb);

src/capi.cpp

+42-23
Original file line numberDiff line numberDiff line change
@@ -382,36 +382,46 @@ void rtcSetUserPointer(int i, void *ptr) { setUserPointer(i, ptr); }
382382

383383
void *rtcGetUserPointer(int i) { return getUserPointer(i).value_or(nullptr); }
384384

385-
int rtcCreatePeerConnection(const rtcConfiguration *config) {
386-
return wrap([config] {
387-
Configuration c;
388-
for (int i = 0; i < config->iceServersCount; ++i)
389-
c.iceServers.emplace_back(string(config->iceServers[i]));
385+
Configuration convertConfiguration(const rtcConfiguration *config)
386+
{
387+
Configuration c;
390388

391-
if (config->proxyServer)
392-
c.proxyServer.emplace(config->proxyServer);
389+
if (!config)
390+
return c;
393391

394-
if (config->bindAddress)
395-
c.bindAddress = string(config->bindAddress);
392+
for (int i = 0; i < config->iceServersCount; ++i)
393+
c.iceServers.emplace_back(string(config->iceServers[i]));
396394

397-
if (config->portRangeBegin > 0 || config->portRangeEnd > 0) {
398-
c.portRangeBegin = config->portRangeBegin;
399-
c.portRangeEnd = config->portRangeEnd;
400-
}
395+
if (config->proxyServer)
396+
c.proxyServer.emplace(config->proxyServer);
401397

402-
c.certificateType = static_cast<CertificateType>(config->certificateType);
403-
c.iceTransportPolicy = static_cast<TransportPolicy>(config->iceTransportPolicy);
404-
c.enableIceTcp = config->enableIceTcp;
405-
c.enableIceUdpMux = config->enableIceUdpMux;
406-
c.disableAutoNegotiation = config->disableAutoNegotiation;
407-
c.forceMediaTransport = config->forceMediaTransport;
398+
if (config->bindAddress)
399+
c.bindAddress = string(config->bindAddress);
408400

409-
if (config->mtu > 0)
410-
c.mtu = size_t(config->mtu);
401+
if (config->portRangeBegin > 0 || config->portRangeEnd > 0) {
402+
c.portRangeBegin = config->portRangeBegin;
403+
c.portRangeEnd = config->portRangeEnd;
404+
}
411405

412-
if (config->maxMessageSize)
413-
c.maxMessageSize = size_t(config->maxMessageSize);
406+
c.certificateType = static_cast<CertificateType>(config->certificateType);
407+
c.iceTransportPolicy = static_cast<TransportPolicy>(config->iceTransportPolicy);
408+
c.enableIceTcp = config->enableIceTcp;
409+
c.enableIceUdpMux = config->enableIceUdpMux;
410+
c.disableAutoNegotiation = config->disableAutoNegotiation;
411+
c.forceMediaTransport = config->forceMediaTransport;
412+
413+
if (config->mtu > 0)
414+
c.mtu = size_t(config->mtu);
415+
416+
if (config->maxMessageSize)
417+
c.maxMessageSize = size_t(config->maxMessageSize);
414418

419+
return c;
420+
}
421+
422+
int rtcCreatePeerConnection(const rtcConfiguration *config) {
423+
return wrap([config] {
424+
Configuration c = convertConfiguration(config);
415425
return emplacePeerConnection(std::make_shared<PeerConnection>(std::move(c)));
416426
});
417427
}
@@ -433,6 +443,15 @@ int rtcDeletePeerConnection(int pc) {
433443
});
434444
}
435445

446+
int rtcSetConfiguration(int pc, const rtcConfiguration *config) {
447+
return wrap([=] {
448+
Configuration c = convertConfiguration(config);
449+
auto peerConnection = getPeerConnection(pc);
450+
peerConnection->setConfiguration(c);
451+
return RTC_ERR_SUCCESS;
452+
});
453+
}
454+
436455
int rtcSetLocalDescriptionCallback(int pc, rtcDescriptionCallbackFunc cb) {
437456
return wrap([&] {
438457
auto peerConnection = getPeerConnection(pc);

src/impl/icetransport.cpp

+111-100
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,10 @@ void IceTransport::LogCallback(juice_log_level_t level, const char *message) {
363363
PLOG(severity) << "juice: " << message;
364364
}
365365

366+
void IceTransport::addIceServers(std::vector<IceServer> servers) {
367+
//TODO
368+
}
369+
366370
#else // USE_NICE == 1
367371

368372
unique_ptr<GMainLoop, void (*)(GMainLoop *)> IceTransport::MainLoop(nullptr, nullptr);
@@ -487,106 +491,7 @@ IceTransport::IceTransport(const Configuration &config, candidate_callback candi
487491
std::vector<IceServer> servers = config.iceServers;
488492
std::shuffle(servers.begin(), servers.end(), utils::random_engine());
489493

490-
// Add one STUN server
491-
bool success = false;
492-
for (auto &server : servers) {
493-
if (server.hostname.empty())
494-
continue;
495-
if (server.type != IceServer::Type::Stun)
496-
continue;
497-
if (server.port == 0)
498-
server.port = 3478; // STUN UDP port
499-
500-
struct addrinfo hints = {};
501-
hints.ai_family = AF_INET; // IPv4
502-
hints.ai_socktype = SOCK_DGRAM;
503-
hints.ai_protocol = IPPROTO_UDP;
504-
hints.ai_flags = AI_ADDRCONFIG;
505-
struct addrinfo *result = nullptr;
506-
if (getaddrinfo(server.hostname.c_str(), std::to_string(server.port).c_str(), &hints,
507-
&result) != 0) {
508-
PLOG_WARNING << "Unable to resolve STUN server address: " << server.hostname << ':'
509-
<< server.port;
510-
continue;
511-
}
512-
513-
for (auto p = result; p; p = p->ai_next) {
514-
if (p->ai_family == AF_INET) {
515-
char nodebuffer[MAX_NUMERICNODE_LEN];
516-
char servbuffer[MAX_NUMERICSERV_LEN];
517-
if (getnameinfo(p->ai_addr, p->ai_addrlen, nodebuffer, MAX_NUMERICNODE_LEN,
518-
servbuffer, MAX_NUMERICSERV_LEN,
519-
NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
520-
PLOG_INFO << "Using STUN server \"" << server.hostname << ":" << server.port
521-
<< "\"";
522-
g_object_set(G_OBJECT(mNiceAgent.get()), "stun-server", nodebuffer, nullptr);
523-
g_object_set(G_OBJECT(mNiceAgent.get()), "stun-server-port",
524-
std::stoul(servbuffer), nullptr);
525-
success = true;
526-
break;
527-
}
528-
}
529-
}
530-
531-
freeaddrinfo(result);
532-
if (success)
533-
break;
534-
}
535-
536-
// Add TURN servers
537-
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);
589-
}
494+
addIceServers(servers);
590495

591496
g_signal_connect(G_OBJECT(mNiceAgent.get()), "component-state-changed",
592497
G_CALLBACK(StateChangeCallback), this);
@@ -888,6 +793,112 @@ bool IceTransport::getSelectedCandidatePair(Candidate *local, Candidate *remote)
888793
return true;
889794
}
890795

796+
797+
798+
void IceTransport::addIceServers(std::vector<IceServer> servers) {
799+
800+
// Add one STUN server
801+
bool success = false;
802+
for (auto &server : servers) {
803+
if (server.hostname.empty())
804+
continue;
805+
if (server.type != IceServer::Type::Stun)
806+
continue;
807+
if (server.port == 0)
808+
server.port = 3478; // STUN UDP port
809+
810+
struct addrinfo hints = {};
811+
hints.ai_family = AF_INET; // IPv4
812+
hints.ai_socktype = SOCK_DGRAM;
813+
hints.ai_protocol = IPPROTO_UDP;
814+
hints.ai_flags = AI_ADDRCONFIG;
815+
struct addrinfo *result = nullptr;
816+
if (getaddrinfo(server.hostname.c_str(), std::to_string(server.port).c_str(), &hints,
817+
&result) != 0) {
818+
PLOG_WARNING << "Unable to resolve STUN server address: " << server.hostname << ':'
819+
<< server.port;
820+
continue;
821+
}
822+
823+
for (auto p = result; p; p = p->ai_next) {
824+
if (p->ai_family == AF_INET) {
825+
char nodebuffer[MAX_NUMERICNODE_LEN];
826+
char servbuffer[MAX_NUMERICSERV_LEN];
827+
if (getnameinfo(p->ai_addr, p->ai_addrlen, nodebuffer, MAX_NUMERICNODE_LEN,
828+
servbuffer, MAX_NUMERICSERV_LEN,
829+
NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
830+
PLOG_INFO << "Using STUN server \"" << server.hostname << ":" << server.port
831+
<< "\"";
832+
g_object_set(G_OBJECT(mNiceAgent.get()), "stun-server", nodebuffer, nullptr);
833+
g_object_set(G_OBJECT(mNiceAgent.get()), "stun-server-port",
834+
std::stoul(servbuffer), nullptr);
835+
success = true;
836+
break;
837+
}
838+
}
839+
}
840+
841+
freeaddrinfo(result);
842+
if (success)
843+
break;
844+
}
845+
846+
// Add TURN servers
847+
for (auto &server : servers) {
848+
if (server.hostname.empty())
849+
continue;
850+
if (server.type != IceServer::Type::Turn)
851+
continue;
852+
if (server.port == 0)
853+
server.port = server.relayType == IceServer::RelayType::TurnTls ? 5349 : 3478;
854+
855+
struct addrinfo hints = {};
856+
hints.ai_family = AF_UNSPEC;
857+
hints.ai_socktype =
858+
server.relayType == IceServer::RelayType::TurnUdp ? SOCK_DGRAM : SOCK_STREAM;
859+
hints.ai_protocol =
860+
server.relayType == IceServer::RelayType::TurnUdp ? IPPROTO_UDP : IPPROTO_TCP;
861+
hints.ai_flags = AI_ADDRCONFIG;
862+
struct addrinfo *result = nullptr;
863+
if (getaddrinfo(server.hostname.c_str(), std::to_string(server.port).c_str(), &hints,
864+
&result) != 0) {
865+
PLOG_WARNING << "Unable to resolve TURN server address: " << server.hostname << ':'
866+
<< server.port;
867+
continue;
868+
}
869+
870+
for (auto p = result; p; p = p->ai_next) {
871+
if (p->ai_family == AF_INET || p->ai_family == AF_INET6) {
872+
char nodebuffer[MAX_NUMERICNODE_LEN];
873+
char servbuffer[MAX_NUMERICSERV_LEN];
874+
if (getnameinfo(p->ai_addr, p->ai_addrlen, nodebuffer, MAX_NUMERICNODE_LEN,
875+
servbuffer, MAX_NUMERICSERV_LEN,
876+
NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
877+
PLOG_INFO << "Using TURN server \"" << server.hostname << ":" << server.port
878+
<< "\"";
879+
NiceRelayType niceRelayType;
880+
switch (server.relayType) {
881+
case IceServer::RelayType::TurnTcp:
882+
niceRelayType = NICE_RELAY_TYPE_TURN_TCP;
883+
break;
884+
case IceServer::RelayType::TurnTls:
885+
niceRelayType = NICE_RELAY_TYPE_TURN_TLS;
886+
break;
887+
default:
888+
niceRelayType = NICE_RELAY_TYPE_TURN_UDP;
889+
break;
890+
}
891+
nice_agent_set_relay_info(mNiceAgent.get(), mStreamId, 1, nodebuffer,
892+
std::stoul(servbuffer), server.username.c_str(),
893+
server.password.c_str(), niceRelayType);
894+
}
895+
}
896+
}
897+
898+
freeaddrinfo(result);
899+
}
900+
}
901+
891902
#endif
892903

893904
} // namespace rtc::impl

src/impl/icetransport.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ class IceTransport : public Transport {
5959

6060
bool getSelectedCandidatePair(Candidate *local, Candidate *remote);
6161

62+
void addIceServers(std::vector<IceServer> servers);
63+
6264
private:
6365
bool outgoing(message_ptr message) override;
6466

0 commit comments

Comments
 (0)