2015-09-01 3 views
8

Je travaille sur un programme pour un usage personnel qui gratte quelques pages Web périodiquement. L'un d'entre eux nécessite l'utilisation de SSL, et son URL principale est en fait un équilibreur de charge qui redirige vers un domaine différent à chaque fois, sur une liste d'une poignée (pas sûr si cela est pertinent). Je suis assez nouveau pour libcurl et SSL en particulier, donc je peux manquer quelque chose d'évident mais je ne le pense pas.Libcurl cesse de fonctionner, erreur de connexion SSL

Le programme fonctionne correctement pendant un certain temps (jusqu'à présent, jamais plus d'une heure), mais une fois qu'il reçoit l'erreur de connexion SSL pour la première fois, il continuera à donner la même erreur à chaque fois. C'est toujours une durée différente, et un nombre différent de demandes réussies, avant que l'échec ne commence.

Le tampon d'erreur contient toujours les éléments suivants: schannel: next InitializeSecurityContext failed: SEC_E_ILLEGAL_MESSAGE (0x80090326) - This error usually occurs when a fatal SSL/TLS alert is received (e.g. handshake failed). More detail may be available in the Windows System event log.

Il n'y a rien utile dans eventvwr. Les recherches effectuées sur ce code d'erreur renvoient à des problèmes liés aux certificats autosignés sur les versions antérieures de Windows Server, mais rien d'autre. Je ne contrôle pas le serveur auquel je me connecte, mais je doute que ce soit une boîte Windows.

Je n'ai plus d'idées ici, donc je vais juste donner des détails qui pourraient être pertinents. Je ne peux pas vraiment publier de code source parce que j'ai supprimé tous les appels de boucles dans plusieurs classes, donc je devrais coller beaucoup de code avant que d'autres puissent le comprendre. J'ai confirmé avec le débogueur Visual Studio que c'est ce que les appels réels se résument à, cependant.

J'initialize libcurl dans le thread principal, avant que d'autres sont créés, comme ceci: curl_global_init(CURL_GLOBAL_WIN32 | CURL_GLOBAL_SSL);

Ensuite, je crée et initialise la poignée de boucle réelle dans un second fil, et seulement dans ce fil, comme ceci:

m_handle = curl_easy_init(); 
curl_easy_setopt(m_handle, CURLOPT_WRITEDATA, this); 
curl_easy_setopt(m_handle, CURLOPT_WRITEFUNCTION, write); 
curl_easy_setopt(m_handle, CURLOPT_DEBUGDATA, this); 
curl_easy_setopt(m_handle, CURLOPT_DEBUGFUNCTION, debug); 
curl_easy_setopt(m_handle, CURLOPT_VERBOSE, 1); 
curl_easy_setopt(m_handle, CURLOPT_ERRORBUFFER, &m_errormsg[0]); 
curl_easy_setopt(m_handle, CURLOPT_FOLLOWLOCATION, 1); 
curl_easy_setopt(m_handle, CURLOPT_COOKIEFILE, ""); 

Je l'ai expérimenté avec la mise à la fois CURLOPT_SSL_VERIFYHOST et CURLOPT_SSL_VERIFYPEER-0 mais cela n'a pas aidé.

J'ai construit libcurl de curl-7.43.0.tar.gz avec nmake /f Makefile.vc mode=static VC=12 ENABLE_WINSSL=yes ENABLE_SSPI=yes MACHINE=x64 DEBUG=yes sur Visual Studio 2013.

Qu'est-ce qui se passe ici et comment puis-je résoudre ce problème?

Répondre

4

Je vais deviner que vous utilisez une seule poignée de CURL pour toutes vos demandes (puisque vous dites « je crée et initialisez la poignée de boucle réelle "). La solution est la plus susceptible de créer un handle CURL pour chaque requête effectuée avec curl_easy_perform(), puis curl_easy_cleanup() immédiatement.

Ce que vous voyez est probablement dû au fait que le serveur a fermé la connexion SSL. Mais votre handle CURL conserve probablement son état tel qu'il est (c'est-à-dire avec la poignée de main terminée), ce qui n'est plus approprié.

+0

Je marque cela comme la réponse pour l'instant, car la prime se termine dans quelques heures, mais je n'ai pas le temps de tester à droite à présent. – Jehjoa

2
CURL *handle = curl_easy_init(); 
char url[] = "https://google.com"; 
curl_easy_setopt(handle, CURLOPT_URL, url); 
curl_easy_perform(handle); 

devrait fonctionner ...

+0

Je suis sûr que c'est le cas mais ce n'est pas ce que je demande ... – Jehjoa