Skip to content

Commit

Permalink
Merge pull request #1768 from namark/more_webrtc_settings
Browse files Browse the repository at this point in the history
Settings for WebRTC signaling server port and ICE server list.
  • Loading branch information
namark committed Mar 3, 2024
2 parents 944ff57 + 58fa2da commit 8d2e135
Show file tree
Hide file tree
Showing 14 changed files with 161 additions and 36 deletions.
49 changes: 49 additions & 0 deletions domain-server/resources/describe-settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
{
"name": "webrtc",
"label": "Networking / WebRTC",
"assignment-types": [ 0, 1, 2, 3, 4, 5, 6 ],
"settings": [
{
"name": "enable_webrtc",
Expand All @@ -99,6 +100,54 @@
"type": "checkbox",
"default": false,
"advanced": true
},
{
"name": "signaling_port",
"label": "Signaling Server TCP Port",
"help": "The main public TCP port domain server listens on to initiate WebRTC connections.",
"default": "40102",
"type": "int",
"advanced": true
},
{
"name": "ice_servers",
"label": "ICE Servers",
"type": "table",
"can_add_new_rows": true,
"help": "WebRTC STUN/TURN servers.",
"numbered": false,
"advanced": true,
"columns": [
{
"name": "url",
"label": "URL",
"can_set": true
},
{
"name": "username",
"label": "User Name",
"placeholder": "Optional",
"can_set": true
},
{
"name": "password",
"label": "Password",
"placeholder": "Optional",
"can_set": true
}
],
"default": [
{
"url": "stun:stun1.l.google.com:19302",
"username": "",
"password": ""
},
{
"url": "stun:stun.schlund.de",
"username": "",
"password": ""
}
]
}
]
},
Expand Down
9 changes: 8 additions & 1 deletion domain-server/src/DomainServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,11 @@ void DomainServer::setupNodeListAndAssignments() {

auto nodeList = DependencyManager::set<LimitedNodeList>(domainServerPort, domainServerDTLSPort);

#if defined(WEBRTC_DATA_CHANNELS)
const QString DOMAIN_SERVER_WEBRTC_ICE_SERVERS_KEY = "webrtc.ice_servers";
nodeList->setWebRTCIceServers(_settingsManager.valueOrDefaultValueForKeyPath(DOMAIN_SERVER_WEBRTC_ICE_SERVERS_KEY).toList());
#endif

// no matter the local port, save it to shared mem so that local assignment clients can ask what it is
nodeList->putLocalPortIntoSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, this,
nodeList->getSocketLocalPort(SocketType::UDP));
Expand Down Expand Up @@ -926,7 +931,9 @@ void DomainServer::setupNodeListAndAssignments() {
// Sets up the WebRTC signaling server that's hosted by the domain server.
void DomainServer::setUpWebRTCSignalingServer() {
// Bind the WebRTC signaling server's WebSocket to its port.
bool isBound = _webrtcSignalingServer->bind(QHostAddress::AnyIPv4, DEFAULT_DOMAIN_SERVER_WS_PORT);
const QString DOMAIN_SERVER_WS_PORT_KEY = "webrtc.signaling_port";
auto settingsPort = _settingsManager.valueOrDefaultValueForKeyPath(DOMAIN_SERVER_WS_PORT_KEY);
bool isBound = _webrtcSignalingServer->bind(QHostAddress::AnyIPv4, settingsPort.isNull() ? DEFAULT_DOMAIN_SERVER_WS_PORT : settingsPort.toInt());
if (!isBound) {
qWarning() << "WebRTC signaling server not bound to port. WebRTC connections are not supported.";
return;
Expand Down
8 changes: 6 additions & 2 deletions libraries/networking/src/LimitedNodeList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

#if defined(Q_OS_WIN)
#include <winsock.h>
#else
#else
#include <arpa/inet.h>
#endif

Expand Down Expand Up @@ -246,6 +246,10 @@ QUdpSocket& LimitedNodeList::getDTLSSocket() {
const WebRTCSocket* LimitedNodeList::getWebRTCSocket() {
return _nodeSocket.getWebRTCSocket();
}

void LimitedNodeList::setWebRTCIceServers(QList<QVariant> iceServers) {
_nodeSocket.setWebRTCIceServers(iceServers);
}
#endif

bool LimitedNodeList::isPacketVerifiedWithSource(const udt::Packet& packet, Node* sourceNode) {
Expand Down Expand Up @@ -506,7 +510,7 @@ qint64 LimitedNodeList::sendUnreliableUnorderedPacketList(NLPacketList& packetLi
}
return bytesSent;
} else {
qCDebug(networking) << "LimitedNodeList::sendUnreliableUnorderedPacketList called without active socket for node"
qCDebug(networking) << "LimitedNodeList::sendUnreliableUnorderedPacketList called without active socket for node"
<< destinationNode << " - not sending.";
return ERROR_SENDING_PACKET_BYTES;
}
Expand Down
1 change: 1 addition & 0 deletions libraries/networking/src/LimitedNodeList.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ class LimitedNodeList : public QObject, public Dependency {
QUdpSocket& getDTLSSocket();
#if defined(WEBRTC_DATA_CHANNELS)
const WebRTCSocket* getWebRTCSocket();
void setWebRTCIceServers(QList<QVariant> iceServers);
#endif


Expand Down
12 changes: 11 additions & 1 deletion libraries/networking/src/NodeList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ NodeList::NodeList(char newOwnerType, int socketListenPort, int dtlsListenPort)
// send a ping punch immediately
connect(&_domainHandler, &DomainHandler::icePeerSocketsReceived, this, &NodeList::pingPunchForDomainServer);

#if defined(WEBRTC_DATA_CHANNELS)
connect(&_domainHandler, &DomainHandler::settingsReceived, this, &NodeList::setWebRTCIceServersFromSettings);
#endif

// FIXME: Can remove this temporary work-around in version 2021.2.0. (New protocol version implies a domain server upgrade.)
// Adjust our canRezAvatarEntities permissions on older domains that do not have this setting.
// DomainServerList and DomainSettings packets can come in either order so need to adjust with both occurrences.
Expand Down Expand Up @@ -497,7 +501,7 @@ void NodeList::sendDomainServerCheckIn() {

// pack our data to send to the domain-server including
// the hostname information (so the domain-server can see which place name we came in on)
packetStream << _ownerType.load() << publicSockAddr.getType() << publicSockAddr << localSockAddr.getType()
packetStream << _ownerType.load() << publicSockAddr.getType() << publicSockAddr << localSockAddr.getType()
<< localSockAddr << _nodeTypesOfInterest.values();
packetStream << DependencyManager::get<AddressManager>()->getPlaceName();

Expand Down Expand Up @@ -1412,6 +1416,12 @@ void NodeList::startThread() {
}


#if defined(WEBRTC_DATA_CHANNELS)
void NodeList::setWebRTCIceServersFromSettings(const QJsonObject& domainSettingsObject) {
LimitedNodeList::setWebRTCIceServers(domainSettingsObject["webrtc"]["ice_servers"].toVariant().toList());
}
#endif

// FIXME: Can remove this work-around in version 2021.2.0. (New protocol version implies a domain server upgrade.)
bool NodeList::adjustCanRezAvatarEntitiesPermissions(const QJsonObject& domainSettingsObject,
NodePermissions& permissions, bool notify) {
Expand Down
6 changes: 5 additions & 1 deletion libraries/networking/src/NodeList.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ public slots:

void processUsernameFromIDReply(QSharedPointer<ReceivedMessage> message);

#if defined(WEBRTC_DATA_CHANNELS)
void setWebRTCIceServersFromSettings(const QJsonObject& domainSettingsObject);
#endif

// FIXME: Can remove these work-arounds in version 2021.2.0. (New protocol version implies a domain server upgrade.)
bool adjustCanRezAvatarEntitiesPermissions(const QJsonObject& domainSettingsObject, NodePermissions& permissions,
bool notify);
Expand Down Expand Up @@ -158,7 +162,7 @@ private slots:

private:
Q_DISABLE_COPY(NodeList)
NodeList() : LimitedNodeList(INVALID_PORT, INVALID_PORT) {
NodeList() : LimitedNodeList(INVALID_PORT, INVALID_PORT) {
assert(false); // Not implemented, needed for DependencyManager templates compile
}
NodeList(char ownerType, int socketListenPort = INVALID_PORT, int dtlsListenPort = INVALID_PORT);
Expand Down
6 changes: 5 additions & 1 deletion libraries/networking/src/udt/NetworkSocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ qint64 NetworkSocket::bytesToWrite(SocketType socketType, const SockAddr& addres


bool NetworkSocket::hasPendingDatagrams() const {
return
return
#if defined(WEBRTC_DATA_CHANNELS)
_webrtcSocket.hasPendingDatagrams() ||
#endif
Expand Down Expand Up @@ -272,6 +272,10 @@ QString NetworkSocket::errorString(SocketType socketType) const {
const WebRTCSocket* NetworkSocket::getWebRTCSocket() {
return &_webrtcSocket;
}

void NetworkSocket::setWebRTCIceServers(QList<QVariant> iceServers) {
_webrtcSocket.setWebRTCIceServers(iceServers);
}
#endif


Expand Down
20 changes: 12 additions & 8 deletions libraries/networking/src/udt/NetworkSocket.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class NetworkSocket : public QObject {
/// @param option The option to set the value of.
/// @param value The option value.
void setSocketOption(SocketType socketType, QAbstractSocket::SocketOption option, const QVariant& value);

/// @brief Gets the value of a UDP or WebRTC socket option.
/// @param socketType The type of socket for which to get the option value.
/// @param option The option to get the value of.
Expand All @@ -55,7 +55,7 @@ class NetworkSocket : public QObject {
/// @param address The address to bind to.
/// @param port The port to bind to.
void bind(SocketType socketType, const QHostAddress& address, quint16 port = 0);

/// @brief Immediately closes and resets the socket.
/// @param socketType The type of socket to close and reset.
void abort(SocketType socketType);
Expand Down Expand Up @@ -90,11 +90,11 @@ class NetworkSocket : public QObject {
/// @brief Gets whether there is a pending datagram waiting to be read.
/// @return <code>true</code> if there is a datagram waiting to be read, <code>false</code> if there isn't.
bool hasPendingDatagrams() const;

/// @brief Gets the size of the next pending datagram, alternating between socket types if both have datagrams to read.
/// @return The size of the next pending datagram.
qint64 pendingDatagramSize();

/// @brief Reads the next datagram per the most recent pendingDatagramSize call if made, otherwise alternating between
/// socket types if both have datagrams to read.
/// @param data The destination to write the data into.
Expand All @@ -103,7 +103,7 @@ class NetworkSocket : public QObject {
/// @return The number of bytes if successfully read, otherwise <code>-1</code>.
qint64 readDatagram(char* data, qint64 maxSize, SockAddr* sockAddr = nullptr);


/// @brief Gets the state of the UDP or WebRTC socket.
/// @param socketType The type of socket for which to get the state.
/// @return The socket state.
Expand All @@ -125,6 +125,10 @@ class NetworkSocket : public QObject {
/// @brief Gets a pointer to the WebRTC socket object.
/// @return A pointer to the WebRTC socket object.
const WebRTCSocket* getWebRTCSocket();

/// @brief Sets the list of WebRTC STUN/TURN servers.
/// @param iceServers The list of STUN/TURN servers.
void setWebRTCIceServers(QList<QVariant> iceServers);
#endif

signals:
Expand All @@ -137,9 +141,9 @@ class NetworkSocket : public QObject {
/// @param socketState The socket's new state.
void stateChanged(SocketType socketType, QAbstractSocket::SocketState socketState);

/// @brief
/// @param socketType
/// @param socketError
/// @brief
/// @param socketType
/// @param socketError
void socketError(SocketType socketType, QAbstractSocket::SocketError socketError);

private slots:
Expand Down
8 changes: 6 additions & 2 deletions libraries/networking/src/udt/Socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ void Socket::rebind(SocketType socketType, quint16 localPort) {
const WebRTCSocket* Socket::getWebRTCSocket() {
return _networkSocket.getWebRTCSocket();
}

void Socket::setWebRTCIceServers(QList<QVariant> iceServers) {
_networkSocket.setWebRTCIceServers(iceServers);
}
#endif

void Socket::setSystemBufferSizes(SocketType socketType) {
Expand All @@ -107,13 +111,13 @@ void Socket::setSystemBufferSizes(SocketType socketType) {

if (i == 0) {
bufferOpt = QAbstractSocket::SendBufferSizeSocketOption;
numBytes = socketType == SocketType::UDP
numBytes = socketType == SocketType::UDP
? udt::UDP_SEND_BUFFER_SIZE_BYTES : udt::WEBRTC_SEND_BUFFER_SIZE_BYTES;
bufferTypeString = "send";

} else {
bufferOpt = QAbstractSocket::ReceiveBufferSizeSocketOption;
numBytes = socketType == SocketType::UDP
numBytes = socketType == SocketType::UDP
? udt::UDP_RECEIVE_BUFFER_SIZE_BYTES : udt::WEBRTC_RECEIVE_BUFFER_SIZE_BYTES;
bufferTypeString = "receive";
}
Expand Down
27 changes: 14 additions & 13 deletions libraries/networking/src/udt/Socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,19 @@ class Socket : public QObject {

public:
using StatsVector = std::vector<std::pair<SockAddr, ConnectionStats::Stats>>;

Socket(QObject* object = 0, bool shouldChangeSocketOptions = true);

quint16 localPort(SocketType socketType) const { return _networkSocket.localPort(socketType); }

// Simple functions writing to the socket with no processing
qint64 writeBasePacket(const BasePacket& packet, const SockAddr& sockAddr);
qint64 writePacket(const Packet& packet, const SockAddr& sockAddr);
qint64 writePacket(std::unique_ptr<Packet> packet, const SockAddr& sockAddr);
qint64 writePacketList(std::unique_ptr<PacketList> packetList, const SockAddr& sockAddr);
qint64 writeDatagram(const char* data, qint64 size, const SockAddr& sockAddr);
qint64 writeDatagram(const QByteArray& datagram, const SockAddr& sockAddr);

void bind(SocketType socketType, const QHostAddress& address, quint16 port = 0);
void rebind(SocketType socketType, quint16 port);
void rebind(SocketType socketType);
Expand All @@ -79,20 +79,21 @@ class Socket : public QObject {
void setMessageFailureHandler(MessageFailureHandler handler) { _messageFailureHandler = handler; }
void setConnectionCreationFilterOperator(ConnectionCreationFilterOperator filterOperator)
{ _connectionCreationFilterOperator = filterOperator; }

void addUnfilteredHandler(const SockAddr& senderSockAddr, BasePacketHandler handler)
{ _unfilteredHandlers[senderSockAddr] = handler; }

void setCongestionControlFactory(std::unique_ptr<CongestionControlVirtualFactory> ccFactory);
void setConnectionMaxBandwidth(int maxBandwidth);

void messageReceived(std::unique_ptr<Packet> packet);
void messageFailed(Connection* connection, Packet::MessageNumber messageNumber);

StatsVector sampleStatsForAllConnections();

#if defined(WEBRTC_DATA_CHANNELS)
const WebRTCSocket* getWebRTCSocket();
void setWebRTCIceServers(QList<QVariant> iceServers);
#endif

#if (PR_BUILD || DEV_BUILD)
Expand All @@ -117,16 +118,16 @@ private slots:
private:
void setSystemBufferSizes(SocketType socketType);
Connection* findOrCreateConnection(const SockAddr& sockAddr, bool filterCreation = false);

// privatized methods used by UDTTest - they are private since they must be called on the Socket thread
ConnectionStats::Stats sampleStatsForConnection(const SockAddr& destination);

std::vector<SockAddr> getConnectionSockAddrs();
void connectToSendSignal(const SockAddr& destinationAddr, QObject* receiver, const char* slot);

Q_INVOKABLE void writeReliablePacket(Packet* packet, const SockAddr& sockAddr);
Q_INVOKABLE void writeReliablePacketList(PacketList* packetList, const SockAddr& sockAddr);

NetworkSocket _networkSocket;
PacketFilterOperator _packetFilterOperator;
PacketHandler _packetHandler;
Expand All @@ -152,10 +153,10 @@ private slots:
int _lastPacketSizeRead { 0 };
SequenceNumber _lastReceivedSequenceNumber;
SockAddr _lastPacketSockAddr;

friend UDTTest;
};

} // namespace udt

#endif // hifi_Socket_h
Loading

0 comments on commit 8d2e135

Please sign in to comment.