当服务器重新启动并且没有恢复重新启动后,libcurl失败,错误代码为56(ssl_read),错误代码为58

时间:2012-08-23 14:30:50

标签: openssl libcurl

如果重新启动服务器,则使用libcurl句柄(简单界面)从客户端到服务器的通信失败。

程序(下面粘贴的代码)创建一个curl句柄,初始化诸如url,证书,超时,请求等选项。然后在每2秒的无限循环中使用curl句柄向服务器发送请求。

观察结果如下:

  1. 程序启动后,正确建立客户端到服务器的通信,并且没有任何错误地交换消息。
  2. 后来我为服务器机器供电。当服务器电源关闭时,curl_easy_perform失败,错误代码= 28,"达到超时(connect()超时!)"。
  3. 然后我启动机器,当机器启动时,观察到curl_easy_perform失败,错误代码= 7,"无法连接到服务器(无法连接到主机)&#34 ;
  4. 一旦curl句柄能够连接到服务器端口,观察到ssl_read错误,curl错误代码= 56,"从对等方接收数据时失败(SSL读取:错误:14094412:SSL例程:SSL3_READ_BYTES:sslv3 alert坏证书,错误0)"
  5. 此后curl_easy_perform失败,错误代码= 58,"本地SSL证书问题(无法使用客户端证书(未找到密钥或错误密码?))"并且在此之后永远不会恢复。
  6. 如果我停止程序并重新启动,则连接成功建立。证书没有变化。
  7. 我无法找到curl_easy_perform因ssl_read错误而失败的原因,以及为什么进一步说错误代码= 58(无法使用客户端证书)。

    由于通信最初使用相同的证书,并且在重新启动流程后,我认为证书没有问题。

    我尝试使用openssl命令验证证书是否正确。

    Linux# openssl x509 -noout -modulus -in /opt/certstore/VcCombined.pem | openssl md5
    fe18e9f364d18eba9f39690563aca836
    
    Linux# openssl rsa -noout -modulus -in /opt/certstore/default.key | openssl md5
    fe18e9f364d18eba9f39690563aca836
    
    Linux# openssl verify -CAfile /opt/certstore/sslca/CACertificate.pem /opt/certstore/VcCombined.pem
    /opt/certstore/VcCombined.pem: OK
    

    我不确定如何进一步调试此问题。如果它是openssl或curl或我的程序的问题。

    客户方:

    curl --version
    
    curl 7.25.0 (i686-pc-linux-gnu) libcurl/7.25.0 OpenSSL/0.9.8f zlib/1.2.1.2 libidn/0.5.6
    Protocols: dict file gopher http https imap imaps pop3 pop3s rtsp smtp smtps telnet
    Features: IDN IPv6 Largefile NTLM NTLM_WB SSL libz
    

    服务器端:

    curl --version
    
    curl 7.25.0 (i686-pc-linux-gnu) libcurl/7.25.0 OpenSSL/1.0.0e zlib/1.2.1.2 libidn/0.5.6
    Protocols: dict file gopher http https imap imaps pop3 pop3s rtsp smtp smtps telnet
    Features: IDN IPv6 Largefile NTLM NTLM_WB SSL libz
    

    程序:

    using namespace std;
    
    static std::string buffer;
    
    static int writer(char *data, size_t size, size_t nmemb, std::string *buffer)
    {
        int result = 0;
    
        if (buffer != NULL)
        {
            buffer->append(data, size * nmemb);
            result = size * nmemb;
        }
    
        return result;
    }
    
    
    int main(void)
    {
        CURL *curl;
        CURLcode res;
        char request[4096];
        char curl_errbuf[CURL_ERROR_SIZE];
        int bytes_read = 0;
    
        FILE *lFile = fopen("/tmp/getguid.xml", "r");
        if (lFile == NULL)
        {
            printf("fopen Error: %s\n", strerror(res));
            return 1;
        }
    
        memset(request, 0, 4096);
        bytes_read = fread(request, sizeof(request), 1, lFile);
        fclose(lFile);
    
        curl = curl_easy_init();
    
        struct curl_slist* lcurlHeaders = NULL;
        lcurlHeaders = curl_slist_append(lcurlHeaders, "Content-Type: text/xml");
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, lcurlHeaders);
        curl_easy_setopt(curl, CURLOPT_URL, "https://10.65.124.221:443/xmlInternal/service-reg/forward");
        curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
        char *lUCSInterfaceName = "eth0";
        curl_easy_setopt(curl, CURLOPT_INTERFACE, lUCSInterfaceName);
        curl_easy_setopt(curl, CURLOPT_SSLCERT, "/opt/certstore/VcCombined.pem");
        curl_easy_setopt(curl, CURLOPT_SSLKEY, "/opt/certstore/default.key");
        curl_easy_setopt(curl, CURLOPT_CAINFO, "/opt/certstore/sslca/CACertificate.pem");
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 1L);
        curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
        curl_easy_setopt(curl, CURLOPT_POST, 1);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, (char*)request);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(request));
        curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_errbuf);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
    
        while(1)
        {
            memset(curl_errbuf, 0, CURL_ERROR_SIZE);
            res = curl_easy_perform(curl);
    
            if(CURLE_OK != res)
                printf("curl_easy_perform Error: %s (%s)\n", curl_easy_strerror(res), curl_errbuf);
            else
                printf("curl_easy_perform succes\n");
    
            sleep(2);
        }
    
        curl_slist_free_all(lCurlHeaders);
        curl_easy_cleanup(curl);
        return 0;
    }
    

0 个答案:

没有答案