Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dtls development #378

Merged
merged 4 commits into from
Jul 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 16 additions & 26 deletions src/association.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#include "association.h"
#include "packet.h"
#include <QTimer>
#include <QCoreApplication>

DtlsAssociation::DtlsAssociation(QHostAddress &address, quint16 port,
const QString &connectionName, std::vector<QString> cmdComponents)
Expand Down Expand Up @@ -44,22 +46,7 @@ DtlsAssociation::DtlsAssociation(QHostAddress &address, quint16 port,

//check if the address field contains a valid host name instead of implicite address
if (hostName.isEmpty()){
QHostInfo host = QHostInfo::fromName(cmdComponents[1]);
// Check if the lookup was successful
if (host.error() != QHostInfo::NoError) {
packetToSend.errorString += "Lookup failed:" + host.errorString();
qDebug() << "Lookup failed:" << host.errorString();
} else {
// Output the host name
foreach (const QHostAddress &resolvedAddress, host.addresses()) {
//if it is an ipv4 save it as addres and fill the hostName with the current hostName
if (resolvedAddress.protocol() == QAbstractSocket::IPv4Protocol){
address = resolvedAddress;
hostName = cmdComponents[1];
}

}
}
hostName = "empty host name";
}

configuration.setLocalCertificate(certificate);
Expand Down Expand Up @@ -101,12 +88,14 @@ void DtlsAssociation::startHandshake()
}

if (!crypto.doHandshake(&socket)){
//socket.waitForBytesWritten();
packetToSend.errorString += " Failed to start a handshake ";
emit errorMessage(tr("%1: failed to start a handshake - %2").arg(name, crypto.dtlsErrorString()));
}
else{

while(true){
socket.waitForReadyRead();
socket.waitForReadyRead(2000);
if(crypto.isConnectionEncrypted() || closeRequest){

break;
Expand Down Expand Up @@ -153,9 +142,9 @@ void DtlsAssociation::readyRead()
}

if (crypto.dtlsError() == QDtlsError::RemoteClosedConnectionError) {
packetToSend.errorString += " Shutdown alert received";
emit errorMessage(tr("%1: shutdown alert received").arg(name));
socket.close();
// packetToSend.errorString += " Shutdown alert received";
// emit errorMessage(tr("%1: shutdown alert received").arg(name));
//socket.close();
pingTimer.stop();
return;
}
Expand All @@ -164,13 +153,14 @@ void DtlsAssociation::readyRead()
} else {
//! [7]
//! [8]
if (!crypto.doHandshake(&socket, dgram)) {
packetToSend.errorString += " handshake error ";
emit errorMessage(tr("%1: handshake error - %2").arg(name, crypto.dtlsErrorString()));
return;
}
QThread::msleep(HANDSHAKE_STEPS_TIMEOUT);
if (!crypto.doHandshake(&socket, dgram)) {
packetToSend.errorString += " handshake error ";
emit errorMessage(tr("%1: handshake error - %2").arg(name, crypto.dtlsErrorString()));
return;
}
//! [8]
crypto.doHandshake(&socket, dgram);
//crypto.doHandshake(&socket, dgram);
//! [9]
if (crypto.isConnectionEncrypted()) {
emit infoMessage(tr("%1: encrypted connection established!").arg(name));
Expand Down
101 changes: 72 additions & 29 deletions src/dtlsserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
#include <algorithm>
#include <QMessageBox>

bool DtlsServer::closeNotifyReceived = false;

namespace {


QString peer_info(const QHostAddress &address, quint16 port)
{
const static QString info = QStringLiteral("(%1:%2)");
Expand All @@ -35,6 +37,7 @@ QString connection_info(QDtls *connection)

} // unnamed namespace


//! [1]
DtlsServer::DtlsServer()
{
Expand Down Expand Up @@ -88,11 +91,14 @@ void DtlsServer::readyRead()
QHostAddress peerAddress;
quint16 peerPort = 0;
const qint64 bytesRead = serverSocket.readDatagram(dgram.data(), dgram.size(),
&peerAddress, &peerPort);
&peerAddress, &peerPort);
if (bytesRead <= 0) {
emit warningMessage(tr("Failed to read a datagram: ") + serverSocket.errorString());
return;
}
// if (dgram.contains("00")){
// int ret = 1;
// }

dgram.resize(bytesRead);
//! [3]
Expand All @@ -115,48 +121,80 @@ void DtlsServer::readyRead()
//! [5]

//! [6]
if ((*client)->isConnectionEncrypted()) {

QDtls * dtlsServer = client->get();

if (dtlsServer->isConnectionEncrypted()) {
QSettings settings(SETTINGSFILE, QSettings::IniFormat);

bool sendResponse = settings.value("sendReponse", false).toBool();
bool sendSmartResponse = settings.value("sendSmartResponse", false).toBool();

QDtls * dtlsServer = client->get();
dgram = dtlsServer->decryptDatagram(&serverSocket, dgram);
QByteArray closeNotify("close notify");



std::vector<QString> recievedPacketInfo = createInfoVect(dtlsServer->peerAddress(), dtlsServer->peerPort(), serverSocket.localAddress(), serverSocket.localPort());
if (dtlsServer->dtlsError() == QDtlsError::RemoteClosedConnectionError){
dgram = closeNotify;
closeNotifyReceived = true;
//dtlsServer->shutdown(&serverSocket);
sendResponse = false;
knownClients.erase(client);

}
Packet recivedPacket = createPacket(recievedPacketInfo, dgram);
emit serverPacketReceived(recivedPacket);

if(settings.value("sendSimpleAck").toString() == "true"){
if(settings.value("sendSimpleAck").toString() == "true" && !dgram.contains("close notify")){
//if(settings.value("sendSimpleAck").toString() == "true" && closeNotifyReceived == false){
sendAck(dtlsServer, dgram);
return;
} else {
errorMessage("close notify recieved");
}

bool sendResponse = settings.value("sendReponse", false).toBool();
bool sendSmartResponse = settings.value("sendReponse", false).toBool();


smartData.clear();

smartData.clear();
//sendSmartResponse = true;
if (sendSmartResponse) {
QList<SmartResponseConfig> smartList;
smartList.append(Packet::fetchSmartConfig(1, SETTINGSFILE));
smartList.append(Packet::fetchSmartConfig(2, SETTINGSFILE));
smartList.append(Packet::fetchSmartConfig(3, SETTINGSFILE));
smartList.append(Packet::fetchSmartConfig(4, SETTINGSFILE));
smartList.append(Packet::fetchSmartConfig(5, SETTINGSFILE));

smartData = Packet::smartResponseMatch(smartList, dgram);
if(!smartData.isEmpty()){
//TODO: if(responseEnableCheck1 == true)
if(serverResonse(client->get())){
return;
}
}


}

if (sendResponse || !smartData.isEmpty()) {
if(serverResonse(client->get())){
// QMessageBox::critical(nullptr, "Connection Error", "server response can't be sent.");
}
//sendResponse =false;

if (sendResponse) {
//if(!dgram.contains("close notify")){

if(serverResonse(client->get())){
return;
// QMessageBox::critical(nullptr, "Connection Error", "server response can't be sent.");
}
//}

}


if ((*client)->dtlsError() == QDtlsError::RemoteClosedConnectionError)
knownClients.erase(client);
// if ((*client)->dtlsError() == QDtlsError::RemoteClosedConnectionError)
// knownClients.erase(client);

return;
}
//! [6]
Expand Down Expand Up @@ -240,13 +278,16 @@ void DtlsServer::sendAck(QDtls *connection, const QByteArray &clientMessage)
if (clientMessage.size()) {
std::vector<QString> sentPacketInfo = createInfoVect(serverSocket.localAddress(), serverSocket.localPort(), connection->peerAddress(), connection->peerPort());
Packet sentPacket = createPacket(sentPacketInfo, clientMessage);
if(connection->writeDatagramEncrypted(&serverSocket, tr("from %1: %2").arg(serverInfo, QString::fromUtf8(clientMessage)).toLatin1())){
QString massageFromTheOtherPeer = "ACK: " + QString::fromUtf8(clientMessage);
sentPacket.hexString = sentPacket.ASCIITohex(massageFromTheOtherPeer);
emit serverPacketSent(sentPacket);
}else{
sentPacket.errorString = "Could not send response";
emit serverPacketSent(sentPacket);
if(connection->isConnectionEncrypted()){

if(connection->writeDatagramEncrypted(&serverSocket, tr("from %1: %2").arg(serverInfo, QString::fromUtf8(clientMessage)).toLatin1())){
QString massageFromTheOtherPeer = "ACK: " + QString::fromUtf8(clientMessage);
sentPacket.hexString = sentPacket.ASCIITohex(massageFromTheOtherPeer);
emit serverPacketSent(sentPacket);
}else{
sentPacket.errorString = "Could not send response";
emit serverPacketSent(sentPacket);
}
}
} else if (connection->dtlsError() == QDtlsError::NoError) {
emit warningMessage(peerInfo + ": " + tr("0 byte dgram, could be a re-connect attempt?"));
Expand Down Expand Up @@ -331,16 +372,18 @@ bool DtlsServer::serverResonse(QDtls* dtlsServer){
}

serverSocket.waitForBytesWritten();
if(dtlsServer->writeDatagramEncrypted(&serverSocket,responsePacket.getByteArray())){
emit serverPacketSent(responsePacket);
return true;
}else{
responsePacket.errorString = "Could not send response";
emit serverPacketSent(responsePacket);
return false;

}
if(dtlsServer->isConnectionEncrypted()){
if(dtlsServer->writeDatagramEncrypted(&serverSocket,responsePacket.getByteArray())){
emit serverPacketSent(responsePacket);
return true;
}else{
responsePacket.errorString = "Could not send response";
emit serverPacketSent(responsePacket);
return false;

}
}

}

Expand Down
6 changes: 5 additions & 1 deletion src/dtlsserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ class DtlsServer : public QObject
Q_OBJECT

public:
static bool closeNotifyReceived; // Initialize static member


QSslCertificate certificate;
QSslKey privateKey;
QSslCertificate caCertificate;
Expand Down Expand Up @@ -51,7 +54,7 @@ class DtlsServer : public QObject




//bool closeNotifyRecieved;
QUdpSocket serverSocket;
QByteArray smartData;

Expand Down Expand Up @@ -88,6 +91,7 @@ public slots:
QDtlsClientVerifier cookieSender;
std::vector<std::unique_ptr<QDtls>> knownClients;


Q_DISABLE_COPY(DtlsServer)
};
//! [0]
Expand Down
Loading
Loading