SSL_read mislukt met SSL_ERROR_SYSCALL-fout

We hebben tls geïmplementeerd met openssl. Tijdens het downloaden van grotere gegevens van de server krijgt u een SSL_ERROR_SYSCALL-fout na het ontvangen van enkele gegevens. Voor kleinere bestanden krijg ik deze fout niet, in staat om zonder enige fout te downloaden. ERR_get_error() toont nul voor grotere bestanden.

We gebruiken het linux- en c++-framework. Hoe de reden voor het falen te vinden? Wat zou de reden van het falen kunnen zijn? graag uw suggesties.


Antwoord 1, autoriteit 100%

SSL_ERROR_SYSCALL geeft aan dat er een probleem is opgetreden met de onderliggende I/O (moet in dit geval TCP zijn). Je kunt het dus proberen met errno.

OpenSSL-help zegt:

SSL_ERROR_SYSCALL

Er is een I/O-fout opgetreden. De OpenSSL-foutwachtrij kan:
bevat meer informatie over de fout. Als de foutenwachtrij leeg is
(d.w.z. ERR_get_error() geeft 0 terug), ret kan worden gebruikt om meer te weten te komen
over de fout: Als ret == 0, is er een EOF waargenomen die in strijd is met de
protocol. Als ret == -1, rapporteerde de onderliggende BIO een I/O-fout (voor
socket I/O op Unix-systemen, raadpleeg errno voor details).


Antwoord 2, autoriteit 45%

Als je de broncode voor SSL_get_error()bekijkt, zul je zien dat het SSL_ERROR_SYSCALLretourneert wanneer het niet zeker is wat er precies is gebeurd. Het is in feite de standaard retourcode voor “onbekend” geval.

Bijvoorbeeld, in mijn geval (niet-blokkerende IO doen met BIO):

int buf;
const int n = SSL_read(ssl, &buf, 0);
const int err = SSL_get_error(ssl, n);
const int st = ERR_get_error();

Als n0 is, is errSSL_ERROR_SYSCALLgewoon omdat. Maar stzal nog steeds 0 zijn, wat aangeeft dat er geen echte fout was. SSL_readheeft zojuist 0 geretourneerd omdat er 0 bytes naar de bufzijn geschreven.

Zoek echter naar errno/ WSAGetLastError()-waarden na de aanroep voor meer details.


Antwoord 3, autoriteit 36%

Controleer of je SSL_read() aanroept met een buffergrootte van 0. Ik heb de volgende fout gemaakt met SSL_pending():

int waitForReadFd = nBuf < bufSize;
if (waitForReadFd)
    FD_SET(fd, &rfds);
// ...
// select
int doReadFd = FD_ISSET(fd, &rfds) || SSL_pending(ssl);
if (doReadFd)
    n = SSL_read(ssl, buf, bufSize - nBuf);

Als nBuf == bufSizeSSL_read() wordt aangeroepen met een buffergrootte van 0 wat leidt tot SSL_ERROR_SYSCALL met errno == 0.

Als u de doReadFd-controle wijzigt, wordt dit probleem voorkomen:

int doReadFd = FD_ISSET(fd, &rfds) || nBuf < bufSize && SSL_pending(ssl);

Antwoord 4, autoriteit 27%

Ik ontdekte dat het probleem de firewall van mijn bedrijf was die de verzoeken blokkeerde. Ga naar huis en het zou moeten werken


Antwoord 5, autoriteit 18%

Het probleem wordt veroorzaakt doordat de netwerkverbinding wordt verbroken en de server opnieuw wordt ingesteld.

Zorg ervoor dat de verbinding in orde is voordat u de gegevens downloadt.

Een soortgelijk probleem kan hier worden gezien bij het gebruik van zwerver.

https://github.com/hashicorp/vagrant/issues/9612


Antwoord 6

We zijn deze fout tegengekomen in een Go-toepassing. We gebruikten een bibliotheek van derden om verbinding te maken met de onderliggende openssl-bibliotheek van Go. Tijdens het lezen van gegevens converteerde de bibliotheek van derden de lengte van de te lezen buffer/gegevens naar C.int, wat 32 bits is. Voor grote gegevens >= 2GB leidt dit tot overflow en wordt een negatieve waarde doorgegeven aan de C.SSL_read-functie.
Het veroorzaakte in dat geval een SSL_ERROR_SYSCALL-fout.

Other episodes