web-dev-qa-db-fra.com

Echec de SSL_read avec une erreur SSL_ERROR_SYSCALL

Nous avons implémenté tls en utilisant openssl. Lors du téléchargement de données plus volumineuses à partir du serveur, l'erreur SSL_ERROR_SYSCALL s'affiche après la réception des données. Pour les fichiers plus petits, je ne reçois pas cette erreur, je peux télécharger sans erreur. ERR_get_error () affiche zéro pour les fichiers plus volumineux.

Nous utilisons linux et le framework c ++. Comment trouver la raison de l'échec? Quelle pourrait être la raison de l'échec? veuillez fournir vos suggestions.

8
pavan

SSL_ERROR_SYSCALL indique qu'un problème est survenu avec les E/S sous-jacentes (Doit être TCP dans ce cas). Donc, vous pouvez essayer de vérifier avec errno.

L'aide OpenSSL indique:

SSL_ERROR_SYSCALL  

Une erreur d’entrée/sortie s’est produite. La file d'erreurs OpenSSL peut contenir Plus d'informations sur l'erreur. Si la file d'erreurs est vide (Ie ERR_get_error () renvoie 0), ret peut être utilisé pour en savoir plus sur À propos de l'erreur: Si ret == 0, un EOF on a observé une violation du protocole . Si ret == -1, le BIO sous-jacent a signalé une erreur d'E/S (pour E/S de socket sur les systèmes Unix, consultez errno pour plus de détails).

7
Jay

Vérifiez si vous appelez SSL_read () avec une taille de tampon de 0. J'ai commis l'erreur suivante avec 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);

Si nBuf == bufSize, SSL_read () sera appelé avec une taille de tampon de 0, ce qui conduit à SSL_ERROR_SYSCALL avec errno et errno == 0.

Changer la vérification de doReadFd évitera ce problème:

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

Si vous examinez le code source de SSL_get_error(), vous verrez qu'il renvoie SSL_ERROR_SYSCALL dès qu'il ne sait pas exactement ce qui s'est passé. C'est fondamentalement le code de retour par défaut pour le cas "inconnu".

Par exemple, dans mon cas (faire IO avec BIO non bloquant):

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

Lorsque n est 0, err sera SSL_ERROR_SYSCALL uniquement parce que. Cependant, st sera toujours 0 indiquant qu'il n'y a pas eu d'erreur réelle. SSL_read vient de renvoyer 0 parce que 0 octet a été écrit dans buf.

Cependant, recherchez les valeurs errno/WSAGetLastError() après l'appel pour plus de détails.

3
wonder.mice

Le problème est dû à la coupure de la connexion réseau et à la réinitialisation du serveur.

Assurez-vous simplement que la connexion est Ok avant de télécharger les données.

Un problème similaire peut être vu ici lors de l'utilisation de vagabond.

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

0
Margach Chris

J'ai constaté que le problème était le pare-feu de mon entreprise bloquant les demandes. Rentre chez toi et ça devrait marcher

0
Samuel Thompson