add processing of DTLS datagrams to domain-server

This commit is contained in:
Stephen Birarda 2014-04-04 09:20:40 -07:00
parent 1c4d44ba4a
commit 7b6ce77690
3 changed files with 59 additions and 42 deletions

View file

@ -101,7 +101,7 @@ bool DomainServer::optionallySetupDTLS() {
gnutls_key_generate(_cookieKey, GNUTLS_COOKIE_KEY_SIZE);
_priorityCache = new gnutls_priority_t;
const char DTLS_PRIORITY_STRING[] = "PERFORMANCE:-VERS-TLS-ALL:+VERS-DTLS1.0:%SERVER_PRECEDENCE";
const char DTLS_PRIORITY_STRING[] = "PERFORMANCE:-VERS-TLS-ALL:+VERS-DTLS1.2:%SERVER_PRECEDENCE";
gnutls_priority_init(_priorityCache, DTLS_PRIORITY_STRING, NULL);
_isUsingDTLS = true;
@ -616,8 +616,6 @@ void DomainServer::readAvailableDTLSDatagrams() {
static socklen_t sockAddrSize = sizeof(senderSockAddr);
while (dtlsSocket.hasPendingDatagrams()) {
qDebug() << "Looking at a datagram";
// check if we have an active DTLS session for this sender
QByteArray peekDatagram(dtlsSocket.pendingDatagramSize(), 0);
@ -642,7 +640,14 @@ void DomainServer::readAvailableDTLSDatagrams() {
}
} else {
// pull the data from this user off the stack and process it
dtlsSocket.readDatagram(peekDatagram.data(), peekDatagram.size());
int receiveCode = gnutls_record_recv(*existingSession->getGnuTLSSession(),
peekDatagram.data(), peekDatagram.size());
if (receiveCode > 0) {
processDatagram(peekDatagram, senderHifiSockAddr);
} else if (gnutls_error_is_fatal(receiveCode)) {
qDebug() << "Fatal error -" << gnutls_strerror(receiveCode) << "- during DTLS handshake with"
<< senderHifiSockAddr;
}
}
} else {
// first we verify the cookie

View file

@ -54,9 +54,8 @@ ssize_t DTLSSession::socketPull(gnutls_transport_ptr_t ptr, void* buffer, size_t
if (pulledSockAddr == session->_destinationSocket) {
// bytes received from the correct sender, return number of bytes received
qDebug() << "Received" << bytesReceived << "on DTLS socket from" << pulledSockAddr;
qDebug() << QByteArray(reinterpret_cast<char*>(buffer), bytesReceived).toHex();
return bytesReceived;
} else {
qDebug() << pulledSockAddr << "is not" << session->_destinationSocket;
}
// we pulled a packet not matching this session, so output that
@ -71,6 +70,7 @@ ssize_t DTLSSession::socketPush(gnutls_transport_ptr_t ptr, const void* buffer,
QUdpSocket& dtlsSocket = session->_dtlsSocket;
qDebug() << "Pushing a message of size" << size << "to" << session->_destinationSocket;
qDebug() << QByteArray(reinterpret_cast<const char*>(buffer), size).toHex();
return dtlsSocket.writeDatagram(reinterpret_cast<const char*>(buffer), size,
session->_destinationSocket.getAddress(), session->_destinationSocket.getPort());
}
@ -87,7 +87,7 @@ DTLSSession::DTLSSession(int end, QUdpSocket& dtlsSocket, HifiSockAddr& destinat
gnutls_dtls_set_mtu(_gnutlsSession, DTLS_MAX_MTU);
const unsigned int DTLS_TOTAL_CONNECTION_TIMEOUT = 10 * DOMAIN_SERVER_CHECK_IN_MSECS;
gnutls_dtls_set_timeouts(_gnutlsSession, 0, DTLS_TOTAL_CONNECTION_TIMEOUT);
gnutls_dtls_set_timeouts(_gnutlsSession, 1, DTLS_TOTAL_CONNECTION_TIMEOUT);
gnutls_transport_set_ptr(_gnutlsSession, this);
gnutls_transport_set_push_function(_gnutlsSession, socketPush);

View file

@ -323,44 +323,56 @@ void NodeList::sendDomainServerCheckIn() {
} else if (!_domainHandler.getIP().isNull()) {
DTLSClientSession* dtlsSession = _domainHandler.getDTLSSession();
bool isUsingDTLS = false;
if (dtlsSession && dtlsSession->completedHandshake()) {
qDebug() << "we can send a DTLS check in!";
} else {
// construct the DS check in packet
QUuid packetUUID = (!_sessionUUID.isNull() ? _sessionUUID : _domainHandler.getAssignmentUUID());
QByteArray domainServerPacket = byteArrayWithPopulatedHeader(PacketTypeDomainListRequest, packetUUID);
QDataStream packetStream(&domainServerPacket, QIODevice::Append);
// pack our data to send to the domain-server
packetStream << _ownerType << _publicSockAddr
<< HifiSockAddr(QHostAddress(getHostOrderLocalAddress()), _nodeSocket.localPort())
<< (quint8) _nodeTypesOfInterest.size();
// copy over the bytes for node types of interest, if required
foreach (NodeType_t nodeTypeOfInterest, _nodeTypesOfInterest) {
packetStream << nodeTypeOfInterest;
if (dtlsSession) {
if (!dtlsSession->completedHandshake()) {
// if the handshake process is not complete then we can't check in, so return
return;
} else {
isUsingDTLS = true;
}
}
// construct the DS check in packet
QUuid packetUUID = (!_sessionUUID.isNull() ? _sessionUUID : _domainHandler.getAssignmentUUID());
QByteArray domainServerPacket = byteArrayWithPopulatedHeader(PacketTypeDomainListRequest, packetUUID);
QDataStream packetStream(&domainServerPacket, QIODevice::Append);
// pack our data to send to the domain-server
packetStream << _ownerType << _publicSockAddr
<< HifiSockAddr(QHostAddress(getHostOrderLocalAddress()), _nodeSocket.localPort())
<< (quint8) _nodeTypesOfInterest.size();
// copy over the bytes for node types of interest, if required
foreach (NodeType_t nodeTypeOfInterest, _nodeTypesOfInterest) {
packetStream << nodeTypeOfInterest;
}
if (!isUsingDTLS) {
writeDatagram(domainServerPacket, _domainHandler.getSockAddr(), QUuid());
const int NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST = 5;
static unsigned int numDomainCheckins = 0;
// send a STUN request every Nth domain server check in so we update our public socket, if required
if (numDomainCheckins++ % NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST == 0) {
sendSTUNRequest();
}
if (_numNoReplyDomainCheckIns >= MAX_SILENT_DOMAIN_SERVER_CHECK_INS) {
// we haven't heard back from DS in MAX_SILENT_DOMAIN_SERVER_CHECK_INS
// so emit our signal that indicates that
emit limitOfSilentDomainCheckInsReached();
}
// increment the count of un-replied check-ins
_numNoReplyDomainCheckIns++;
}
} else {
gnutls_record_send(*dtlsSession->getGnuTLSSession(), domainServerPacket.data(), domainServerPacket.size());
}
const int NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST = 5;
static unsigned int numDomainCheckins = 0;
// send a STUN request every Nth domain server check in so we update our public socket, if required
if (numDomainCheckins++ % NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST == 0) {
sendSTUNRequest();
}
if (_numNoReplyDomainCheckIns >= MAX_SILENT_DOMAIN_SERVER_CHECK_INS) {
// we haven't heard back from DS in MAX_SILENT_DOMAIN_SERVER_CHECK_INS
// so emit our signal that indicates that
emit limitOfSilentDomainCheckInsReached();
}
// increment the count of un-replied check-ins
_numNoReplyDomainCheckIns++;
}
}