Thank you Ray and Daniel for the quick response. Our application is 
multithreaded and different threads will use it (Curl) for their own purposes 
but the code here is isolated to a single thread (there is no sharing of curl 
objects).

This is the code that is using curl:

               CURL *curl_handle;
               CURLcode curlcode;
               const char *server_addr_str;
               const char *proxy;
               int proxyauth = CURLAUTH_NONE;
               time_t     send_ts = 0;
               long cache_timeout_age = CURL_DEFAULT_DNS_CACHE_TIMEOUT;
               long fresh_connect = CURL_DEFAULT_FRESH_CONNECT;
               int iResult;

               curl_handle = curl_easy_init();
               if (!(curl_handle)) {
                              printf("%s(): curl_easy_init returned NULL", 
__func__);
                              goto ERROUT;
               }
               // with libcurl, necessary to use http:// or https:// even 
though the protocol is not http
               snprintf(url, sizeof(url), "https://%s:%d";, handle->server_name, 
port);
               curlcode = curl_easy_setopt(curl_handle, CURLOPT_URL, url);
               if (curlcode != CURLE_OK) {
                              printf("%s(): curl_easy_setopt(CURLOPT_URL) 
returned %d (%s)", __func__, curlcode, curl_easy_strerror(curlcode));
                              curl_easy_cleanup(curl_handle);
                              goto ERROUT;
               }
               if (proxy) {
                              curlcode = curl_easy_setopt(curl_handle, 
CURLOPT_PROXY, proxy);
                              if (curlcode != CURLE_OK) {
                                             printf("%s(): 
curl_easy_setopt(CURLOPT_PROXY) returned %d (%s)", __func__, curlcode, 
curl_easy_strerror(curlcode));
                                             curl_easy_cleanup(curl_handle);
                                             goto ERROUT;
                              }
                              // if using an HTTP proxy, do a CONNECT
                              curlcode = curl_easy_setopt(curl_handle, 
CURLOPT_HTTPPROXYTUNNEL, 1);
                              if (curlcode != CURLE_OK) {
                                             printf("%s(): 
curl_easy_setopt(CURLOPT_HTTPPROXYTUNNEL) returned %d (%s)", __func__, 
curlcode, curl_easy_strerror(curlcode));
                                             curl_easy_cleanup(curl_handle);
                                             goto ERROUT;
                              }
                              if (proxyauth != CURLAUTH_NONE) {
                                             curlcode = 
curl_easy_setopt(curl_handle, CURLOPT_PROXYAUTH, proxyauth);
                                             if (curlcode != CURLE_OK) {
                                                            printf("%s(): 
curl_easy_setopt(CURLOPT_PROXYAUTH) returned %d (%s)", __func__, curlcode, 
curl_easy_strerror(curlcode));
                                                            
curl_easy_cleanup(curl_handle);
                                                            goto ERROUT;
                                             }
                              }
                              send_ts = time(NULL);
               }
               curlcode = curl_easy_setopt(curl_handle, CURLOPT_PORT, port);
               if (curlcode != CURLE_OK) {
                              printf("%s(): curl_easy_setopt(CURLOPT_PORT) 
returned %d (%s)", __func__, curlcode, curl_easy_strerror(curlcode));
                              curl_easy_cleanup(curl_handle);
                              goto ERROUT;
               }
               curlcode = curl_easy_setopt(curl_handle, CURLOPT_CONNECT_ONLY, 
1);
               if (curlcode != CURLE_OK) {
                              printf("%s(): 
curl_easy_setopt(CURLOPT_CONNECT_ONLY) returned %d (%s)", __func__, curlcode, 
curl_easy_strerror(curlcode));
                              curl_easy_cleanup(curl_handle);
                              goto ERROUT;
               }
               curlcode = curl_easy_setopt(curl_handle, CURLOPT_IPRESOLVE, 
CURL_IPRESOLVE_V4);                    // XXX TODO a few changes needed for ipv6
               if (curlcode != CURLE_OK) {
                              printf("%s(): curl_easy_setopt(CURLOPT_IPRESOLVE) 
returned %d (%s)", __func__, curlcode, curl_easy_strerror(curlcode));
                              curl_easy_cleanup(curl_handle);
                              goto ERROUT;
               }
               curlcode = curl_easy_setopt(curl_handle, 
CURLOPT_SSL_CTX_FUNCTION, *fa_sslctx_config_func);
               if (curlcode != CURLE_OK) {
                              printf("%s(): 
curl_easy_setopt(CURLOPT_SSL_CTX_FUNCTION) returned %d (%s)", __func__, 
curlcode, curl_easy_strerror(curlcode));
                              curl_easy_cleanup(curl_handle);
                              goto ERROUT;
               }
               curlcode = curl_easy_setopt(curl_handle, CURLOPT_SSL_CTX_DATA, 
handle);
               if (curlcode != CURLE_OK) {
                              printf("%s(): 
curl_easy_setopt(CURLOPT_SSL_CTX_DATA) returned %d (%s)", __func__, curlcode, 
curl_easy_strerror(curlcode));
                              curl_easy_cleanup(curl_handle);
                              goto ERROUT;
               }

               curlcode = curl_easy_setopt(curl_handle, CURLOPT_USE_SSL, 
CURLUSESSL_ALL);
               if (curlcode != CURLE_OK) {
                              printf("%s(): curl_easy_setopt(CURLOPT_USE_SSL) 
returned %d (%s)", __func__, curlcode, curl_easy_strerror(curlcode));
                              curl_easy_cleanup(curl_handle);
                              goto ERROUT;
               }
               curlcode = curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 
insecure ? 0 : 1);
               if (curlcode != CURLE_OK) {
                              printf("%s(): 
curl_easy_setopt(CURLOPT_SSL_VERIFYPEER) returned %d (%s)", __func__, curlcode, 
curl_easy_strerror(curlcode));
                              curl_easy_cleanup(curl_handle);
                              goto ERROUT;
               }
               curlcode = curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 
insecure ? 0 : 2);
               if (curlcode != CURLE_OK) {
                              printf("%s(): 
curl_easy_setopt(CURLOPT_SSL_VERIFYHOST) returned %d (%s)", __func__, curlcode, 
curl_easy_strerror(curlcode));
                              curl_easy_cleanup(curl_handle);
                              goto ERROUT;
               }
               curlcode = curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
               if (curlcode != CURLE_OK) {
                              printf("%s(): curl_easy_setopt(CURLOPT_NOSIGNAL) 
returned %d (%s)", __func__, curlcode, curl_easy_strerror(curlcode));
                              curl_easy_cleanup(curl_handle);
                              goto ERROUT;
               }
               curlcode = curl_easy_setopt(curl_handle, CURLOPT_ERRORBUFFER, 
handle->curl_error);
               if (curlcode != CURLE_OK) {
                              printf("%s(): 
curl_easy_setopt(CURLOPT_ERRORBUFFER) returned %d (%s)", __func__, curlcode, 
curl_easy_strerror(curlcode));
                              curl_easy_cleanup(curl_handle);
                              goto ERROUT;
               }

               if (fresh_connection) {
                              fresh_connect     = 1L;
                              cache_timeout_age = 0L;
                              handle->last_connection_refresh = time(NULL);
                              handle->force_fresh_connection  = false;
                              printf("%s(): Forcing connection refresh and 
clearing DNS cache", __func__);
               }

               curlcode = curl_easy_setopt(curl_handle, CURLOPT_FRESH_CONNECT, 
fresh_connect);
               if (curlcode != CURLE_OK) {
                              printf("%s(): 
curl_easy_setopt(CURLOPT_FRESH_CONNECT) returned %d (%s)", __func__, curlcode, 
curl_easy_strerror(curlcode));
                              /* the rest of the connection has been setup 
properly, continue on error */
               }
               curlcode = curl_easy_setopt(curl_handle, 
CURLOPT_DNS_CACHE_TIMEOUT, cache_timeout_age);
               if (curlcode != CURLE_OK) {
                              printf("%s(): 
curl_easy_setopt(CURLOPT_DNS_CACHE_TIMEOUT) returned %d (%s)", __func__, 
curlcode, curl_easy_strerror(curlcode));
                              /* the rest of the connection has been setup 
properly, continue on error */
               }

               printf("%s(): running curl_easy_perform", __func__);
               curlcode = curl_easy_perform(curl_handle);
               if (curlcode != CURLE_OK) {
                              switch (curlcode) {
                                             case CURLE_SSL_CERTPROBLEM:
                                                            printf("%s(): 
received curl error: %s for %s port %d, we will assume that our certificate is 
bad, we remove current "
                                                                                
            "certificate to obtain a new one via EST", __func__, 
curl_easy_strerror(curlcode), url, port);
                                                            break;

                                             case CURLE_SSL_CACERT:
                                                            printf("%s(): 
received curl error: %s for %s port %d we need to manually obtain a new CA 
certificate", __func__,
                                                                                
            curl_easy_strerror(curlcode), url, port);
                                                            break;

                                             case CURLE_SSL_CONNECT_ERROR:
                                                            if 
(strncmp(handle->curl_error, CURL_UNKNOWN_CA_SSL_ERROR, 
sizeof(CURL_UNKNOWN_CA_SSL_ERROR) - 1) == 0) {
                                                                           
printf("%s(): curl_easy_perform returned SSL connect error for %s port %d.",
                                                                                
                           __func__, url, port);
                                                            } else {
                                                                           
printf("%s(): curl_easy_perform SSL connect error (%s) for %s port %d", 
__func__, handle->curl_error, url, port);
                                                            }
                                                            break;

                                             case CURLE_COULDNT_RESOLVE_PROXY:
                                             case CURLE_COULDNT_RESOLVE_HOST:
                                                            /* When running 
from a VM, on wake we sometimes see issues with resolving hostnames, force a 
fresh connection on next request */
                                                            if 
((handle->last_connection_refresh == 0) ||
                                                                           
((time(NULL) - handle->last_connection_refresh) > 
MIN_CONNECTION_REFRESH_PERIOD)) {
                                                                           
handle->force_fresh_connection = true;
                                                            }
                                                            /* fall through */
                                             default:
                                                            printf("%s(): 
curl_easy_perform for %s port %d returned %d (%s) (%s)", __func__, url, port, 
curlcode,
                                                                                
            curl_easy_strerror(curlcode), handle->curl_error);
                                                            break;
                              }
                              curl_easy_cleanup(curl_handle);
                              /*
                               * Here we differentiate between whether a server 
is unreachable
                              * or another error has occurred such as a 
timeouts or an invalid
                              * response from the server.
                              *
                              * We consider the server unreachable if we can't 
connect to it,
                              * we failed to resolve the host/proxy, we've been
                              * redirected too many times or an SSL connect 
error was
                              * encountered.
                              */
                              if ((curlcode == CURLE_COULDNT_CONNECT) ||
                                             (curlcode == 
CURLE_COULDNT_RESOLVE_HOST) ||
                                             (curlcode == 
CURLE_COULDNT_RESOLVE_PROXY) ||
                                             (curlcode == 
CURLE_TOO_MANY_REDIRECTS) ||
                                             (curlcode == 
CURLE_SSL_CONNECT_ERROR)) {
                                             if (handle->connection_failed_cb) {
                                                            
handle->connection_failed_cb(send_ts);
                                             }
                              } else if (handle->connection_reachable_cb) {
                                             handle->connection_reachable_cb();
                              }
                              goto ERROUT;
               }
               printf("%s(): curl_easy_perform returned", __func__);


From: curl-library [mailto:[email protected]] On Behalf Of Ray 
Satiro via curl-library
Sent: Thursday, December 08, 2016 4:44 PM
To: [email protected]
Cc: Ray Satiro <[email protected]>
Subject: Re: Access violation in Curl_hash_add

On 12/8/2016 6:27 PM, Jake Fehr (jfehr) wrote:

Our use of Curl is pretty straightforward:


1.      Call curl_easy_init()

2.      Make (and check the result of) several calls to curl_easy_setopt(), 
setting up proxy, url, port, ssl, etc.

3.      Call curl_easy_perform()

I can provide the code if needed.

Please provide a self contained example that can be used to reproduce, your 
curl_version() and the OS you're using.
-------------------------------------------------------------------
List admin: https://cool.haxx.se/list/listinfo/curl-library
Etiquette:  https://curl.haxx.se/mail/etiquette.html

Reply via email to