Include socket type in domain packets

Required for user client info sent to assignment clients from the domain server.
This commit is contained in:
David Rowe 2021-09-04 10:36:13 +12:00
parent ff72b422b3
commit 911dc2aff3
10 changed files with 52 additions and 40 deletions

View file

@ -51,20 +51,20 @@ NodeConnectionData NodeConnectionData::fromDataStream(QDataStream& dataStream, c
dataStream >> newHeader.lastPingTimestamp;
SocketType publicSocketType, localSocketType;
dataStream >> newHeader.nodeType
>> newHeader.publicSockAddr >> newHeader.localSockAddr
>> publicSocketType >> newHeader.publicSockAddr >> localSocketType >> newHeader.localSockAddr
>> newHeader.interestList >> newHeader.placeName;
newHeader.publicSockAddr.setType(publicSocketType);
newHeader.localSockAddr.setType(localSocketType);
// A WebRTC web client doesn't necessarily know it's public Internet or local network addresses, and for WebRTC they aren't
// needed: for WebRTC, the data channel ID is the important thing. The client's public Internet IP address still needs to
// be known for domain access permissions, though, and this can be obtained from the WebSocket signaling connection.
if (senderSockAddr.getSocketType() == SocketType::WebRTC) {
// WEBRTC TODO: Rather than setting the SocketType here, serialize and deserialize the SocketType in the leading byte of
// the 5 bytes used to encode the IP address.
newHeader.publicSockAddr.setSocketType(SocketType::WebRTC);
newHeader.localSockAddr.setSocketType(SocketType::WebRTC);
// WEBRTC TODO: Set the public Internet address obtained from the WebSocket used in WebRTC signaling.
// For WebRTC connections, the user client doesn't know the WebRTC data channel ID that the domain server is using as its
// SockAddr port, so set the port values here.
if (senderSockAddr.getType() == SocketType::WebRTC) {
if (newHeader.publicSockAddr.getType() != SocketType::WebRTC
|| newHeader.localSockAddr.getType() != SocketType::WebRTC) {
qDebug() << "Inconsistent WebRTC socket types!";
}
newHeader.publicSockAddr.setPort(senderSockAddr.getPort()); // We don't know whether it's a public or local connection
newHeader.localSockAddr.setPort(senderSockAddr.getPort()); // so set both ports.

View file

@ -196,7 +196,9 @@ bool Node::isIgnoringNodeWithID(const QUuid& nodeID) const {
QDataStream& operator<<(QDataStream& out, const Node& node) {
out << node._type;
out << node._uuid;
out << node._publicSocket.getType();
out << node._publicSocket;
out << node._localSocket.getType();
out << node._localSocket;
out << node._permissions;
out << node._isReplicated;
@ -205,10 +207,15 @@ QDataStream& operator<<(QDataStream& out, const Node& node) {
}
QDataStream& operator>>(QDataStream& in, Node& node) {
SocketType publicSocketType, localSocketType;
in >> node._type;
in >> node._uuid;
in >> publicSocketType;
in >> node._publicSocket;
node._publicSocket.setType(publicSocketType);
in >> localSocketType;
in >> node._localSocket;
node._localSocket.setType(localSocketType);
in >> node._permissions;
in >> node._isReplicated;
in >> node._localID;

View file

@ -494,7 +494,8 @@ 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 << localSockAddr << _nodeTypesOfInterest.toList();
packetStream << _ownerType.load() << publicSockAddr.getType() << publicSockAddr << localSockAddr.getType()
<< localSockAddr << _nodeTypesOfInterest.toList();
packetStream << DependencyManager::get<AddressManager>()->getPlaceName();
if (!domainIsConnected) {
@ -879,14 +880,19 @@ void NodeList::processDomainServerRemovedNode(QSharedPointer<ReceivedMessage> me
void NodeList::parseNodeFromPacketStream(QDataStream& packetStream) {
NewNodeInfo info;
SocketType publicSocketType, localSocketType;
packetStream >> info.type
>> info.uuid
>> publicSocketType
>> info.publicSocket
>> localSocketType
>> info.localSocket
>> info.permissions
>> info.isReplicated
>> info.sessionLocalID
>> info.connectionSecretUUID;
info.publicSocket.setType(publicSocketType);
info.localSocket.setType(localSocketType);
// if the public socket address is 0 then it's reachable at the same IP
// as the domain server
@ -894,10 +900,6 @@ void NodeList::parseNodeFromPacketStream(QDataStream& packetStream) {
info.publicSocket.setAddress(_domainHandler.getIP());
}
// WEBRTC TODO: Handle WebRTC-connected nodes. Probably need to include SocketType in SockAddr << and >>
info.publicSocket.setSocketType(SocketType::UDP);
info.localSocket.setSocketType(SocketType::UDP);
addNewNode(info);
}

View file

@ -137,21 +137,14 @@ QDebug operator<<(QDebug debug, const SockAddr& sockAddr) {
}
QDataStream& operator<<(QDataStream& dataStream, const SockAddr& sockAddr) {
// Don't include socketType because it can be implied from the type of connection used.
// WEBRTC TODO: Reconsider this.
// Don't include socket type because ICE packets must not have it.
dataStream << sockAddr._address << sockAddr._port;
return dataStream;
}
QDataStream& operator>>(QDataStream& dataStream, SockAddr& sockAddr) {
// Don't include socketType because it can be implied from the type of connection used.
// WEBRTC TODO: Reconsider this.
// Don't include socket type because ICE packets must not have it.
dataStream >> sockAddr._address >> sockAddr._port;
// Set default for non-WebRTC code.
// WEBRTC TODO: Reconsider this.
sockAddr.setSocketType(SocketType::UDP);
return dataStream;
}

View file

@ -40,9 +40,9 @@ public:
bool operator==(const SockAddr& rhsSockAddr) const;
bool operator!=(const SockAddr& rhsSockAddr) const { return !(*this == rhsSockAddr); }
SocketType getSocketType() const { return _socketType; }
SocketType getType() const { return _socketType; }
SocketType* getSocketTypePointer() { return &_socketType; }
void setSocketType(const SocketType socketType) { _socketType = socketType; }
void setType(const SocketType socketType) { _socketType = socketType; }
const QHostAddress& getAddress() const { return _address; }
QHostAddress* getAddressPointer() { return &_address; }

View file

@ -19,8 +19,8 @@
/// @brief The types of network socket.
enum class SocketType {
Unknown, ///< Unknown socket type.
enum class SocketType : uint8_t {
Unknown, ///< Socket type unknown or not set.
UDP, ///< UDP socket.
WebRTC ///< WebRTC socket. A WebRTC data channel presented as a UDP-style socket.
};

View file

@ -126,7 +126,7 @@ qintptr NetworkSocket::socketDescriptor(SocketType socketType) const {
qint64 NetworkSocket::writeDatagram(const QByteArray& datagram, const SockAddr& sockAddr) {
switch (sockAddr.getSocketType()) {
switch (sockAddr.getType()) {
case SocketType::UDP:
// WEBRTC TODO: The Qt documentation says that the following call shouldn't be used if the UDP socket is connected!!!
// https://doc.qt.io/qt-5/qudpsocket.html#writeDatagram
@ -197,7 +197,7 @@ qint64 NetworkSocket::readDatagram(char* data, qint64 maxSize, SockAddr* sockAdd
_lastSocketTypeRead = SocketType::UDP;
_pendingDatagramSizeSocketType = SocketType::Unknown;
if (sockAddr) {
sockAddr->setSocketType(SocketType::UDP);
sockAddr->setType(SocketType::UDP);
return _udpSocket.readDatagram(data, maxSize, sockAddr->getAddressPointer(), sockAddr->getPortPointer());
} else {
return _udpSocket.readDatagram(data, maxSize);
@ -206,7 +206,7 @@ qint64 NetworkSocket::readDatagram(char* data, qint64 maxSize, SockAddr* sockAdd
_lastSocketTypeRead = SocketType::WebRTC;
_pendingDatagramSizeSocketType = SocketType::Unknown;
if (sockAddr) {
sockAddr->setSocketType(SocketType::WebRTC);
sockAddr->setType(SocketType::WebRTC);
return _webrtcSocket.readDatagram(data, maxSize, sockAddr->getAddressPointer(), sockAddr->getPortPointer());
} else {
return _webrtcSocket.readDatagram(data, maxSize);
@ -214,7 +214,7 @@ qint64 NetworkSocket::readDatagram(char* data, qint64 maxSize, SockAddr* sockAdd
}
#else
if (sockAddr) {
sockAddr->setSocketType(SocketType::UDP);
sockAddr->setType(SocketType::UDP);
return _udpSocket.readDatagram(data, maxSize, sockAddr->getAddressPointer(), sockAddr->getPortPointer());
} else {
return _udpSocket.readDatagram(data, maxSize);

View file

@ -27,7 +27,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
case PacketType::DomainConnectRequestPending: // keeping the old version to maintain the protocol hash
return 17;
case PacketType::DomainList:
return static_cast<PacketVersion>(DomainListVersion::HasConnectReason);
return static_cast<PacketVersion>(DomainListVersion::SocketTypes);
case PacketType::EntityAdd:
case PacketType::EntityClone:
case PacketType::EntityEdit:
@ -72,10 +72,12 @@ PacketVersion versionForPacketType(PacketType packetType) {
return static_cast<PacketVersion>(DomainConnectionDeniedVersion::IncludesExtraInfo);
case PacketType::DomainConnectRequest:
return static_cast<PacketVersion>(DomainConnectRequestVersion::HasCompressedSystemInfo);
return static_cast<PacketVersion>(DomainConnectRequestVersion::SocketTypes);
case PacketType::DomainListRequest:
return static_cast<PacketVersion>(DomainListRequestVersion::SocketTypes);
case PacketType::DomainServerAddedNode:
return static_cast<PacketVersion>(DomainServerAddedNodeVersion::PermissionsGrid);
return static_cast<PacketVersion>(DomainServerAddedNodeVersion::SocketTypes);
case PacketType::EntityScriptCallMethod:
return static_cast<PacketVersion>(EntityScriptCallMethodVersion::ClientCallable);

View file

@ -368,7 +368,13 @@ enum class DomainConnectRequestVersion : PacketVersion {
HasTimestamp,
HasReason,
HasSystemInfo,
HasCompressedSystemInfo
HasCompressedSystemInfo,
SocketTypes
};
enum class DomainListRequestVersion : PacketVersion {
PreSocketTypes = 22,
SocketTypes
};
enum class DomainConnectionDeniedVersion : PacketVersion {
@ -379,7 +385,8 @@ enum class DomainConnectionDeniedVersion : PacketVersion {
enum class DomainServerAddedNodeVersion : PacketVersion {
PrePermissionsGrid = 17,
PermissionsGrid
PermissionsGrid,
SocketTypes
};
enum class DomainListVersion : PacketVersion {
@ -389,7 +396,8 @@ enum class DomainListVersion : PacketVersion {
GetMachineFingerprintFromUUIDSupport,
AuthenticationOptional,
HasTimestamp,
HasConnectReason
HasConnectReason,
SocketTypes
};
enum class AudioVersion : PacketVersion {

View file

@ -245,7 +245,7 @@ qint64 Socket::writeDatagram(const char* data, qint64 size, const SockAddr& sock
}
qint64 Socket::writeDatagram(const QByteArray& datagram, const SockAddr& sockAddr) {
auto socketType = sockAddr.getSocketType();
auto socketType = sockAddr.getType();
// don't attempt to write the datagram if we're unbound. Just drop it.
// _networkSocket.writeDatagram will return an error anyway, but there are