ich habe ein großes Problem mit SSLSockets, ich mache schon seit Tagen rum,
aber irgendwie finde ich die Lösung einfach nicht.
Ich habe einen Anwendung geschrieben welche Client Anfragen in Threads bearbeitet.
Im Main Thread läuft eine Klasse welche von QTcpServer abgeleitet ist, und deren incomingConnection wie folgt aussieht
Code: Alles auswählen
void Server::incomingConnection(int socketDescriptor){
QThread* thread = new QThread;
Worker* worker = new Worker(socketDescriptor);
worker->moveToThread(thread);
connect(worker, SIGNAL(errorThread(QString)), this, SLOT(errorThread(QString)));
connect(thread, SIGNAL(started()), worker, SLOT(process()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
}
Code: Alles auswählen
Worker::Worker(int id)
{
this->socketDescriptor = id;
}Code: Alles auswählen
void Worker::process(){
_st = Settings::getInstance();
//initialize variables
sslSocket = 0;
requestData = "";
finishedEmitted= false;
closeConnectionCalled = false;
sslSocket = new QSslSocket(0);
if(sslSocket->setSocketDescriptor(socketDescriptor)){
QString serverKeyPath = _st->serverPrivateKey;
QString intermediateCertPath = _st->serverIntermediateCert;
sslSocket->ignoreSslErrors();
sslSocket->setCiphers(QSslSocket::supportedCiphers());
sslSocket->setProtocol(QSsl::AnyProtocol);
sslSocket->setPeerVerifyMode(QSslSocket::VerifyNone);
sslSocket->setPrivateKey(serverKeyPath);
sslSocket->setLocalCertificate(QSslCertificate::fromPath(_st->serverCertificate)[0]);
if(intermediateCertPath.count()>0){
sslSocket->addExtraCertificate(QSslCertificate::fromPath(_st->serverIntermediateCert)[0]);
}else{
sslSocket->addExtraCertificate(QSslCertificate::fromPath(_st->serverCertificate)[0]);
}
connect(sslSocket,SIGNAL(sslErrors(QList<QSslError>)),this,SLOT(sslError(QList<QSslError>)),Qt::DirectConnection);
connect(sslSocket,SIGNAL(readyRead()),this,SLOT(readyRead()),Qt::DirectConnection);
connect(sslSocket,SIGNAL(disconnected()),this,SLOT(disconnected()),Qt::DirectConnection);
connect(sslSocket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(socketError(QAbstractSocket::SocketError)),Qt::DirectConnection);
sslSocket->startServerEncryption();
bool success = sslSocket->waitForReadyRead(10000);
if(!success){
sslSocket->abort();
finish();
}
}und am Ende der ReadyRead Methode wird die finish Methode aufgerufen.
Das Einlesen der Daten funktioniert wunderbar, ebenso das bearbeiten, abspeichern
in der Datenbank und die Ausgabe des Ergebnisses.
Hier möchte ich nun das QSslSocket Objekt vom Heap löschen.
Der Code der finish Methode lautet wie folgt.
Code: Alles auswählen
void Worker::finish(){
if(!finishedEmitted){
finishedEmitted = true;
closeConnection();
mutex.lock();
mutex.unlock();
if(sslSocket){
sslSocket->blockSignals(true);
sslSocket->disconnect();
//sslSocket->deleteLater();
delete sslSocket;
sslSocket = 0;
}
emit finished();
}
}Code: Alles auswählen
void Worker::closeConnection(){
if(closeConnectionCalled)
return;
if(sslSocket){
mutex.lock();
if(sslSocket->isValid() && sslSocket->isOpen() && !closeConnectionCalled){
closeConnectionCalled = true;
sslSocket->close();
}
mutex.unlock();
}
}im Destruktor, egal ob mit delete oder sslSocket->deleteLater, es gibt immer hässliche Segmentation Faults.
Wenn man mit dem Debugger reingeht sieht man dass diese entstehen wenn die geladenen Zertifkate
gelöscht werden sollen.
Wenn ich die Zertifikate anders wieim obigen Code so wie hier reinlade, gibt es ein Segmentation Fault beim
Versuch die QHostAddress zu deleten. wobei _st->certServerCertificate ein QSslCertificate ist.
Code: Alles auswählen
QSslCertificate localCert = QSslCertificate(_st->certServerCertificate);
sslSocket->setLocalCertificate (localCert);
Hat jemand von Euch eine Idee, ich bin echt am verzweifeln ...
Ich hab schon sehr viel gegoogelt, aber keine ähnlichen Probleme gefunden.
Daraus schliese ich dass ich wohl etwas grundlegendes falsch mache ...
Gruß Till