Libcurl перестает работать, ошибка подключения SSL

Я работаю над программой для личного пользования, которая периодически очищает несколько веб-страниц. Один из них требует использования SSL, а его основной URL фактически является балансировщиком нагрузки, который каждый раз перенаправляет на другой домен из списка нескольких (не уверен, что это актуально). Я совершенно новичок в libcurl и SSL, в частности, поэтому я могу упустить что-то очевидное, но я так не думаю.

Некоторое время программа работает нормально (пока что никогда не дольше, чем час), но как только она впервые получает ошибку соединения SSL, она будет каждый раз выдавать одну и ту же ошибку. Это всегда разное количество времени и разное количество успешных запросов, прежде чем он начнет давать сбои.

Буфер ошибок всегда содержит следующее: 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.

Там нет ничего полезного в eventvwr, Поиски по этому коду ошибки возвращают результаты о проблемах с самозаверяющими сертификатами в более ранних версиях Windows Server, но мало что еще. Я не контролирую сервер, к которому подключаюсь, но сомневаюсь, что это Windows-бокс.

У меня закончились идеи, поэтому я просто собираюсь рассказать о любых деталях, которые могут иметь отношение к делу. Я действительно не могу опубликовать какой-либо реальный исходный код, потому что я абстрагировал все вызовы curl в нескольких классах, поэтому мне пришлось бы вставить много шаблонного кода, чтобы другие могли его понять. С помощью отладчика Visual Studio я подтвердил, что это то, к чему сводятся реальные вызовы.

Я инициализирую libcurl в главном потоке перед созданием других, например так: curl_global_init(CURL_GLOBAL_WIN32 | CURL_GLOBAL_SSL);

Затем я создаю и инициализирую фактическую ручку curl во втором потоке, и только в этом потоке, вот так:

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, "");

Я экспериментировал с настройкой обоих CURLOPT_SSL_VERIFYHOST а также CURLOPT_SSL_VERIFYPEER до 0, но это не помогло.

Я построил libcurl из curl-7.43.0.tar.gz с nmake /f Makefile.vc mode=static VC=12 ENABLE_WINSSL=yes ENABLE_SSPI=yes MACHINE=x64 DEBUG=yes на Visual Studio 2013.

Что здесь происходит и как я могу это исправить?

8

Решение

Я предполагаю, что вы используете один дескриптор CURL для всех ваших запросов (поскольку вы говорите: «Я создаю и инициализирую»). фактический дескриптор curl «). Решение, скорее всего, создаст один дескриптор CURL для каждого запроса, выполненного с помощью curl_easy_perform (), а затем сразу же curl_easy_cleanup ().

То, что вы видите, вероятно, вызвано отключением SSL-соединения сервером. Но ваш дескриптор CURL, скорее всего, сохраняет свое состояние как есть (то есть с завершенным рукопожатием), что больше не подходит.

4

Другие решения

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

должно сработать…

2

По вопросам рекламы [email protected]