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_SYSCALL
retourneert 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 n
0 is, is err
SSL_ERROR_SYSCALL
gewoon omdat. Maar st
zal nog steeds 0 zijn, wat aangeeft dat er geen echte fout was. SSL_read
heeft zojuist 0 geretourneerd omdat er 0 bytes naar de buf
zijn 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 == bufSize
SSL_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.