kopia lustrzana https://gitlab.com/eliggett/wfview
Fix error when deleting server connections
I still think that maybe this should be done better?merge-requests/2/head
rodzic
ba60181c69
commit
cf1ee895cf
|
@ -2420,7 +2420,7 @@ void rigCommander::printHex(const QByteArray &pdata, bool printVert, bool printH
|
|||
|
||||
void rigCommander::dataFromServer(QByteArray data)
|
||||
{
|
||||
qDebug() << "emit dataForComm()";
|
||||
//qDebug() << "emit dataForComm()";
|
||||
emit dataForComm(data);
|
||||
}
|
||||
|
||||
|
|
228
udpserver.cpp
228
udpserver.cpp
|
@ -1,5 +1,7 @@
|
|||
#include "udpserver.h"
|
||||
|
||||
#define STALE_CONNECTION 15
|
||||
|
||||
udpServer::udpServer(SERVERCONFIG config) :
|
||||
config(config)
|
||||
{
|
||||
|
@ -53,30 +55,53 @@ udpServer::~udpServer()
|
|||
|
||||
foreach(CLIENT * client, controlClients)
|
||||
{
|
||||
client->idleTimer->stop();
|
||||
delete client->idleTimer;
|
||||
client->pingTimer->stop();
|
||||
delete client->pingTimer;
|
||||
client->wdTimer->stop();
|
||||
delete client->wdTimer;
|
||||
//delete& client; // Not sure how safe this is?
|
||||
if (client->idleTimer != Q_NULLPTR)
|
||||
{
|
||||
client->idleTimer->stop();
|
||||
delete client->idleTimer;
|
||||
}
|
||||
if (client->pingTimer != Q_NULLPTR) {
|
||||
client->pingTimer->stop();
|
||||
delete client->pingTimer;
|
||||
}
|
||||
if (client->wdTimer != Q_NULLPTR) {
|
||||
client->wdTimer->stop();
|
||||
delete client->wdTimer;
|
||||
}
|
||||
delete client;
|
||||
controlClients.removeAll(client);
|
||||
}
|
||||
foreach(CLIENT * client, civClients)
|
||||
{
|
||||
client->idleTimer->stop();
|
||||
delete client->idleTimer;
|
||||
client->pingTimer->stop();
|
||||
delete client->pingTimer;
|
||||
//delete& client; // Not sure how safe this is?
|
||||
if (client->idleTimer != Q_NULLPTR)
|
||||
{
|
||||
client->idleTimer->stop();
|
||||
delete client->idleTimer;
|
||||
}
|
||||
if (client->pingTimer != Q_NULLPTR) {
|
||||
client->pingTimer->stop();
|
||||
delete client->pingTimer;
|
||||
}
|
||||
delete client;
|
||||
civClients.removeAll(client);
|
||||
}
|
||||
foreach(CLIENT * client, audioClients)
|
||||
{
|
||||
client->pingTimer->stop();
|
||||
delete client->pingTimer;
|
||||
//delete& client; // Not sure how safe this is?
|
||||
if (client->idleTimer != Q_NULLPTR)
|
||||
{
|
||||
client->idleTimer->stop();
|
||||
delete client->idleTimer;
|
||||
}
|
||||
if (client->pingTimer != Q_NULLPTR) {
|
||||
client->pingTimer->stop();
|
||||
delete client->pingTimer;
|
||||
}
|
||||
delete client;
|
||||
audioClients.removeAll(client);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (udpControl != Q_NULLPTR) {
|
||||
udpControl->close();
|
||||
delete udpControl;
|
||||
|
@ -101,14 +126,17 @@ void udpServer::controlReceived()
|
|||
QNetworkDatagram datagram = udpControl->receiveDatagram();
|
||||
QByteArray r = datagram.data();
|
||||
CLIENT* current = Q_NULLPTR;
|
||||
if (datagram.senderPort() == 65535 || datagram.senderPort() == 0)
|
||||
if (datagram.senderAddress().isNull() || datagram.senderPort() == 65535 || datagram.senderPort() == 0)
|
||||
return;
|
||||
|
||||
foreach(CLIENT * client, controlClients)
|
||||
{
|
||||
if (client->ipAddress == datagram.senderAddress() && client->port == datagram.senderPort())
|
||||
if (client != Q_NULLPTR)
|
||||
{
|
||||
current = client;
|
||||
if (client->ipAddress == datagram.senderAddress() && client->port == datagram.senderPort())
|
||||
{
|
||||
current = client;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (current == Q_NULLPTR)
|
||||
|
@ -129,13 +157,13 @@ void udpServer::controlReceived()
|
|||
current->pingTimer = new QTimer();
|
||||
current->idleTimer = new QTimer();
|
||||
current->wdTimer = new QTimer();
|
||||
connect(current->pingTimer, &QTimer::timeout, this, std::bind(&udpServer::sendPing, this, current, (quint16)0x00, false));
|
||||
connect(current->pingTimer, &QTimer::timeout, this, std::bind(&udpServer::sendPing, this, &controlClients, current, (quint16)0x00, false));
|
||||
connect(current->idleTimer, &QTimer::timeout, this, std::bind(&udpServer::sendIdle, this, current, (quint16)0x00));
|
||||
connect(current->wdTimer, &QTimer::timeout, this, std::bind(&udpServer::sendWatchdog, this, current));
|
||||
connect(current->wdTimer, &QTimer::timeout, this, std::bind(&udpServer::sendWatchdog, this, controlClients, current));
|
||||
current->pingTimer->start(100);
|
||||
current->idleTimer->start(100);
|
||||
current->wdTimer->start(10000);
|
||||
qDebug() << "New connection created from :" << current->ipAddress.toString() << ":" << QString::number(current->port);
|
||||
qDebug() << "New Control connection created from :" << current->ipAddress.toString() << ":" << QString::number(current->port);
|
||||
controlClients.append(current);
|
||||
}
|
||||
|
||||
|
@ -167,12 +195,8 @@ void udpServer::controlReceived()
|
|||
{
|
||||
qDebug() << current->ipAddress.toString() << ": Received 'disconnect' request";
|
||||
sendIdle(current, gotSeq);
|
||||
current->idleTimer->stop();
|
||||
current->pingTimer->stop();
|
||||
current->wdTimer->stop();
|
||||
delete current;
|
||||
controlClients.removeOne(current);
|
||||
|
||||
//current->wdTimer->stop(); // Keep watchdog running to delete stale connection.
|
||||
deleteConnection(&controlClients, current);
|
||||
}
|
||||
break;
|
||||
case (0x14):
|
||||
|
@ -186,11 +210,11 @@ void udpServer::controlReceived()
|
|||
if (r[16] == (char)0x00)
|
||||
{
|
||||
current->rxPingSeq = qFromLittleEndian<quint32>(r.mid(0x11, 4));
|
||||
sendPing(current, gotSeq, true);
|
||||
sendPing(&controlClients, current, gotSeq, true);
|
||||
}
|
||||
else if (r[16] == (char)0x01) {
|
||||
// A Reply to our ping!
|
||||
if (gotSeq == current->pingSeq) {
|
||||
if (gotSeq == current->pingSeq || gotSeq == current->pingSeq - 1) {
|
||||
current->pingSeq++;
|
||||
}
|
||||
else {
|
||||
|
@ -284,14 +308,20 @@ void udpServer::civReceived()
|
|||
|
||||
CLIENT* current = Q_NULLPTR;
|
||||
|
||||
if (datagram.senderPort() == 65535 || datagram.senderPort() == 0)
|
||||
if (datagram.senderAddress().isNull() || datagram.senderPort() == 65535 || datagram.senderPort() == 0)
|
||||
return;
|
||||
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
|
||||
foreach(CLIENT * client, civClients)
|
||||
{
|
||||
if (client->ipAddress == datagram.senderAddress() && client->port == datagram.senderPort())
|
||||
if (client != Q_NULLPTR)
|
||||
{
|
||||
current = client;
|
||||
if (client->ipAddress == datagram.senderAddress() && client->port == datagram.senderPort())
|
||||
{
|
||||
current = client;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (current == Q_NULLPTR)
|
||||
|
@ -309,11 +339,11 @@ void udpServer::civReceived()
|
|||
current->pingTimer = new QTimer();
|
||||
current->idleTimer = new QTimer();
|
||||
current->wdTimer = new QTimer();
|
||||
connect(current->pingTimer, &QTimer::timeout, this, std::bind(&udpServer::sendPing, this, current, (quint16)0x00, false));
|
||||
connect(current->pingTimer, &QTimer::timeout, this, std::bind(&udpServer::sendPing, this, &civClients, current, (quint16)0x00, false));
|
||||
connect(current->idleTimer, &QTimer::timeout, this, std::bind(&udpServer::sendIdle, this, current, (quint16)0x00));
|
||||
current->pingTimer->start(100);
|
||||
current->idleTimer->start(100);
|
||||
qDebug() << "New connection created from :" << current->ipAddress.toString() << ":" << QString::number(current->port);
|
||||
qDebug() << "New CIV connection created from :" << current->ipAddress.toString() << ":" << QString::number(current->port);
|
||||
civClients.append(current);
|
||||
}
|
||||
|
||||
|
@ -345,10 +375,7 @@ void udpServer::civReceived()
|
|||
{
|
||||
qDebug() << current->ipAddress.toString() << ": Received 'disconnect' request";
|
||||
sendIdle(current, gotSeq);
|
||||
current->idleTimer->stop();
|
||||
current->pingTimer->stop();
|
||||
delete current;
|
||||
controlClients.removeOne(current);
|
||||
deleteConnection(&civClients, current);
|
||||
|
||||
}
|
||||
break;
|
||||
|
@ -363,11 +390,11 @@ void udpServer::civReceived()
|
|||
if (r[16] == (char)0x00)
|
||||
{
|
||||
current->rxPingSeq = qFromLittleEndian<quint32>(r.mid(0x11, 4));
|
||||
sendPing(current, gotSeq, true);
|
||||
sendPing(&civClients, current, gotSeq, true);
|
||||
}
|
||||
else if (r[16] == (char)0x01) {
|
||||
// A Reply to our ping!
|
||||
if (gotSeq == current->pingSeq) {
|
||||
if (gotSeq == current->pingSeq || gotSeq == current->pingSeq - 1) {
|
||||
current->pingSeq++;
|
||||
}
|
||||
else {
|
||||
|
@ -382,7 +409,7 @@ void udpServer::civReceived()
|
|||
quint8 temp = r[0] - 0x15;
|
||||
if ((quint8)r[16] == 0xc1 && (quint8)r[17] == temp)
|
||||
{
|
||||
qDebug() << "Got CIV from server: " << r.mid(21);
|
||||
//qDebug() << "Got CIV from server: " << r.mid(21);
|
||||
emit haveDataFromServer(r.mid(21));
|
||||
}
|
||||
}
|
||||
|
@ -400,15 +427,19 @@ void udpServer::audioReceived()
|
|||
QByteArray r = datagram.data();
|
||||
CLIENT* current = Q_NULLPTR;
|
||||
|
||||
if (datagram.senderPort() == 65535 || datagram.senderPort() == 0)
|
||||
if (datagram.senderAddress().isNull() || datagram.senderPort() == 65535 || datagram.senderPort() == 0)
|
||||
return;
|
||||
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
|
||||
foreach(CLIENT * client, audioClients)
|
||||
{
|
||||
|
||||
if (client != Q_NULLPTR && client->ipAddress == datagram.senderAddress() && client->port == datagram.senderPort())
|
||||
if (client != Q_NULLPTR)
|
||||
{
|
||||
current = client;
|
||||
if (client->ipAddress == datagram.senderAddress() && client->port == datagram.senderPort())
|
||||
{
|
||||
current = client;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (current == Q_NULLPTR)
|
||||
|
@ -424,9 +455,9 @@ void udpServer::audioReceived()
|
|||
current->innerPingSeq = (quint16)rand();
|
||||
current->pingSeq = (quint8)rand() << 8 | (quint8)rand();
|
||||
current->pingTimer = new QTimer();
|
||||
connect(current->pingTimer, &QTimer::timeout, this, std::bind(&udpServer::sendPing, this, current, (quint16)0x00, false));
|
||||
connect(current->pingTimer, &QTimer::timeout, this, std::bind(&udpServer::sendPing, this, &audioClients, current, (quint16)0x00, false));
|
||||
current->pingTimer->start(100);
|
||||
qDebug() << "New connection created from :" << current->ipAddress.toString() << ":" << QString::number(current->port);
|
||||
qDebug() << "New Audio connection created from :" << current->ipAddress.toString() << ":" << QString::number(current->port);
|
||||
audioClients.append(current);
|
||||
}
|
||||
|
||||
|
@ -458,10 +489,7 @@ void udpServer::audioReceived()
|
|||
{
|
||||
qDebug() << current->ipAddress.toString() << ": Received 'disconnect' request";
|
||||
sendIdle(current, gotSeq);
|
||||
current->pingTimer->stop();
|
||||
delete current;
|
||||
controlClients.removeOne(current);
|
||||
|
||||
deleteConnection(&audioClients, current);
|
||||
}
|
||||
break;
|
||||
case (0x14):
|
||||
|
@ -475,9 +503,9 @@ void udpServer::audioReceived()
|
|||
if (r[16] == (char)0x00)
|
||||
{
|
||||
current->rxPingSeq = qFromLittleEndian<quint32>(r.mid(0x11, 4));
|
||||
sendPing(current, gotSeq, true);
|
||||
sendPing(&audioClients, current, gotSeq, true);
|
||||
}
|
||||
else if (r[16] == (char)0x01) {
|
||||
if (gotSeq == current->pingSeq || gotSeq == current->pingSeq - 1) {
|
||||
// A Reply to our ping!
|
||||
if (gotSeq == current->pingSeq) {
|
||||
current->pingSeq++;
|
||||
|
@ -537,6 +565,8 @@ void udpServer::sendIAmReady(CLIENT* c)
|
|||
|
||||
void udpServer::sendIdle(CLIENT* c, quint16 seq)
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
|
||||
if (seq == 0x00)
|
||||
{
|
||||
seq = c->txSeq;
|
||||
|
@ -558,8 +588,20 @@ void udpServer::sendIdle(CLIENT* c, quint16 seq)
|
|||
|
||||
|
||||
#define PING_SIZE 0x15
|
||||
void udpServer::sendPing(CLIENT* c, quint16 seq, bool reply)
|
||||
void udpServer::sendPing(QList<CLIENT*> *l,CLIENT* c, quint16 seq, bool reply)
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
// Also use to detect "stale" connections
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
|
||||
if (c->lastHeard.secsTo(now) > STALE_CONNECTION)
|
||||
{
|
||||
qDebug() << "Deleting stale connection " << c->ipAddress.toString();
|
||||
deleteConnection(l, c);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//qDebug() << c->ipAddress.toString() << ": Sending Ping";
|
||||
|
||||
quint32 pingSeq = 0;
|
||||
|
@ -723,10 +765,13 @@ void udpServer::sendTokenResponse(CLIENT* c, quint8 type)
|
|||
}
|
||||
|
||||
#define WATCHDOG_SIZE 0x14
|
||||
void udpServer::sendWatchdog(CLIENT* c)
|
||||
void udpServer::sendWatchdog(QList<CLIENT*> l,CLIENT* c)
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
qint32 deciSeconds = (qint32)c->timeConnected.msecsTo(now)/100;
|
||||
|
||||
qint32 deciSeconds = (qint32)c->timeConnected.msecsTo(now) / 100;
|
||||
|
||||
quint8 p[WATCHDOG_SIZE];
|
||||
memset(p, 0x0, sizeof(p));
|
||||
|
@ -747,6 +792,8 @@ void udpServer::sendWatchdog(CLIENT* c)
|
|||
|
||||
void udpServer::sendStatus(CLIENT* c)
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
|
||||
qDebug() << c->ipAddress.toString() << ": Sending Status";
|
||||
|
||||
quint8 p[STATUS_SIZE];
|
||||
|
@ -780,33 +827,66 @@ void udpServer::sendStatus(CLIENT* c)
|
|||
}
|
||||
|
||||
|
||||
#define SEND_SIZE 17
|
||||
#define SEND_SIZE 0x15
|
||||
void udpServer::dataForServer(QByteArray d)
|
||||
{
|
||||
|
||||
CLIENT* current = Q_NULLPTR;
|
||||
//qDebug() << "Server got:" << d;
|
||||
foreach(CLIENT * client, civClients)
|
||||
{
|
||||
qDebug() << "Sending CIV data to " << client->ipAddress.toString();
|
||||
quint8 p[SEND_SIZE];
|
||||
memset(p, 0x0, sizeof(p));
|
||||
qToLittleEndian(client->txSeq, p + 0x06);
|
||||
qToLittleEndian(client->myId, p + 0x08);
|
||||
qToLittleEndian(client->remoteId, p + 0x0c);
|
||||
if (client != Q_NULLPTR && client->connected) {
|
||||
quint8 p[SEND_SIZE];
|
||||
memset(p, 0x0, sizeof(p));
|
||||
qToLittleEndian(client->txSeq, p + 0x06);
|
||||
qToLittleEndian(client->myId, p + 0x08);
|
||||
qToLittleEndian(client->remoteId, p + 0x0c);
|
||||
|
||||
QByteArray t = QByteArray::fromRawData((const char*)p, sizeof(p));
|
||||
p[0x10] = (char)0xc1;
|
||||
qToLittleEndian((quint16)t.length(), p + 0x11);
|
||||
qToLittleEndian((quint16)sizeof(p) + t.length(), p + 0x00);
|
||||
QByteArray t = QByteArray::fromRawData((const char*)p, sizeof(p));
|
||||
p[0x10] = (char)0xc1;
|
||||
qToLittleEndian((quint16)t.length(), p + 0x11);
|
||||
qToLittleEndian(client->connSeq, p + 0x12);
|
||||
qToLittleEndian((quint16)sizeof(p) + t.length()+d.length(), p + 0x00);
|
||||
|
||||
t.append(QByteArray::fromRawData((const char*)p, sizeof(p)));
|
||||
qToLittleEndian(client->connSeq, p + 0x12);
|
||||
client->socket->writeDatagram(t, client->ipAddress, client->port);
|
||||
client->connSeq++;
|
||||
client->txSeq++;
|
||||
t.append(QByteArray::fromRawData((const char*)p, sizeof(p)));
|
||||
t.append(d);
|
||||
|
||||
QMutexLocker locker(&mutex);
|
||||
client->connSeq++;
|
||||
client->txSeq++;
|
||||
client->socket->writeDatagram(t, client->ipAddress, client->port);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void udpServer::deleteConnection(QList<CLIENT*> *l, CLIENT* c)
|
||||
{
|
||||
QList<CLIENT*>::iterator it = l->begin();
|
||||
while (it != l->end()) {
|
||||
CLIENT* client = *it;
|
||||
if (client != Q_NULLPTR && client == c) {
|
||||
qDebug() << "Deleting connection to: " << c->ipAddress.toString() << ":" << QString::number(c->port);
|
||||
if (client->idleTimer != Q_NULLPTR) {
|
||||
client->idleTimer->stop();
|
||||
delete client->idleTimer;
|
||||
}
|
||||
if (client->pingTimer != Q_NULLPTR) {
|
||||
client->pingTimer->stop();
|
||||
delete client->pingTimer;
|
||||
}
|
||||
if (client->wdTimer != Q_NULLPTR) {
|
||||
client->wdTimer->stop();
|
||||
delete client->wdTimer;
|
||||
}
|
||||
qDebug() << "Number of clients: " << l->length();
|
||||
it = l->erase(it);
|
||||
qDebug() << "Number of clients (after erase): " << l->length();
|
||||
}
|
||||
else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
delete c;
|
||||
c = Q_NULLPTR;
|
||||
}
|
||||
|
|
10
udpserver.h
10
udpserver.h
|
@ -75,6 +75,8 @@ private:
|
|||
quint8 txCodec;
|
||||
quint16 rxSampleRate;
|
||||
quint16 txSampleRate;
|
||||
|
||||
|
||||
};
|
||||
|
||||
void controlReceived();
|
||||
|
@ -82,14 +84,16 @@ private:
|
|||
void audioReceived();
|
||||
void sendIAmHere(CLIENT* c);
|
||||
void sendIAmReady(CLIENT* c);
|
||||
void sendPing(CLIENT* c, quint16 seq, bool reply);
|
||||
void sendPing(QList<CLIENT*> *l,CLIENT* c, quint16 seq, bool reply);
|
||||
void sendIdle(CLIENT* c, quint16 seq);
|
||||
void sendLoginResponse(CLIENT* c, quint16 seq, bool allowed);
|
||||
void sendCapabilities(CLIENT* c);
|
||||
void sendConnectionInfo(CLIENT* c);
|
||||
void sendTokenResponse(CLIENT* c,quint8 type);
|
||||
void sendWatchdog(CLIENT* c);
|
||||
void sendWatchdog(QList<CLIENT*> l, CLIENT* c);
|
||||
void sendStatus(CLIENT* c);
|
||||
void deleteConnection(QList<CLIENT*> *l, CLIENT* c);
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -113,6 +117,8 @@ private:
|
|||
QByteArray data;
|
||||
};
|
||||
|
||||
QMutex mutex; // Used for critical operations.
|
||||
|
||||
QList <CLIENT*> controlClients = QList<CLIENT*>();
|
||||
QList <CLIENT*> civClients = QList<CLIENT*>();
|
||||
QList <CLIENT*> audioClients = QList<CLIENT*>();
|
||||
|
|
Ładowanie…
Reference in New Issue