cURL / Mailing Lists / curl-library / Single Mail

curl-library

Unknown SSL protocol error with multithreaded client

From: Shalem Raju <shalem_at_gmail.com>
Date: Fri, 30 Jul 2010 17:11:51 +0530

Hi,
We are using multithreaded client with libcurl to connect to tomcat 5.5
web server.
We are getting Error : SSL connect error,
                    detaild error : Unknown SSL protocol error in connection
to www.openssl.org:443
                    Further error details: err=-1, detail=5,
errnomsg=Resource temporarily unavailable
                  ( Further error details are given by modifying one line
in curl7.15.0/lib/ssluse.c
                  orig : failf(data, "Unknown SSL protocol error in
connection to %s:%d ", conn->host.name, conn->port);
                  modified : failf(data, "Unknown SSL protocol error in
connection to %s:%d err=%d, detail=%d, errdetail=%d, errnomsg=%s", conn->
host.name, conn->port, err, detail, errdetail, strerror(curlerrno)) )
 I found that this is error is coming during receving the server hello.
Surprisingly if I debug the program with break points at every step of
handshake it is working fine.

When we are using same source without any threads(commenting the
pthread_create call and calling the function normally ) it is working
fine.
Please help me in resolving this issue.

Thanks in advance.

libcurl version, openssl version, sample code and configuration details are
available below.

OS: AIX

libcurl version : curl-7.15.0
libcurl configuration details :
configure CC="xlC_r" --enable-static=yes --enable-shared=no --enable-thread
--enable-verbose --enable-debug --enable-cookies --enable-nonblocking

openssl version: openssl-0.9.8o
openssl config details :
config threads no-shared -D_REENTRANT

At tomcat serverl.xml is added with below configuration to enabled HTTPS

<Connector port="8443" maxHttpHeaderSize="8192"
               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
               enableLookups="false" disableUploadTimeout="true"
               acceptCount="100" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" />

Sample threaded code used:

#include <stdio.h>
#include <pthread.h>
#include <curl.h>

#define NUMT 1

/* we have this global to let the callback get easy access to it */
static pthread_mutex_t *lockarray;

#include <openssl/crypto.h>
static void lock_callback(int mode, int type, const char *file, int line)
{
  (void)file;
  (void)line;
  if (mode & CRYPTO_LOCK) {
    pthread_mutex_lock(&(lockarray[type]));
  }
  else {
    pthread_mutex_unlock(&(lockarray[type]));
  }
}

static unsigned long thread_id(void)
{
  unsigned long ret;

  ret=(unsigned long)pthread_self();
  return(ret);
}

static void init_locks(void)
{
  int i;

  lockarray=(pthread_mutex_t *)OPENSSL_malloc(CRYPTO_num_locks() *
                                            sizeof(pthread_mutex_t));
  for (i=0; i<CRYPTO_num_locks(); i++) {
    pthread_mutex_init(&(lockarray[i]),NULL);
  }

  CRYPTO_set_id_callback((unsigned long (*)())thread_id);
  CRYPTO_set_locking_callback(lock_callback);
}

static void kill_locks(void)
{
  int i;

  CRYPTO_set_locking_callback(NULL);
  for (i=0; i<CRYPTO_num_locks(); i++)
    pthread_mutex_destroy(&(lockarray[i]));

  OPENSSL_free(lockarray);
}

/* List of URLs to fetch.*/
const char * const urls[]= {
  "https://www.openssl.org/",
  "https://www.openssl.org/",
  "https://www.sf.net/",
  "https://www.sf.net/",
};

char curlError [CURL_ERROR_SIZE];
static void *pull_one_url(void *url)
{
 CURL *curl;
 CURLcode errornum;
 const char *p;

 curl = curl_easy_init();
 curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curlError);
 curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
 curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3);
 curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);

 curl_easy_setopt(curl, CURLOPT_URL, url);
 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER,0 );
 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
 curl_easy_setopt(curl, CURLOPT_SSL_CIPHER_LIST,"ALL:!EXP");

 errornum = curl_easy_perform(curl);

 p = curl_easy_strerror(errornum );
 fprintf(stderr, "operation reult : %s\n", p);
 fprintf(stderr, "Detailed Error code: %s\n", curlError);

 curl_easy_cleanup(curl);

 return NULL;
}

int main(int argc, char **argv)
{
  pthread_t tid[NUMT];
  int i;
  int error;
  (void)argc; /* we don't use any arguments in this example */
  (void)argv;

  /* Must initialize libcurl before any threads are started */
  curl_global_init(CURL_GLOBAL_ALL);

  init_locks();

  for(i=0; i< NUMT; i++) {
    error = pthread_create(&tid[i],
                           NULL, /* default attributes please */
                           pull_one_url,
                           (void *)urls[i]);
    if(0 != error)
      fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i,
error);
    else
      fprintf(stderr, "Thread %d, gets %s\n", i, urls[i]);
  }

  /* now wait for all threads to terminate */
  for(i=0; i< NUMT; i++) {
    error = pthread_join(tid[i], NULL);
    fprintf(stderr, "Thread %d terminated\n", i);
  }

  kill_locks();

  return 0;
}

Compiled using :
xlC_r -D_REENTRANT -DPOSIX_THREADS threaded-ssl.c -I
/XXX/libcurl/curl-7.15.9-ssl098/include/curl/ -I
/XXX/libcurl/openssl-0.9.8o-install/include/ -lpthread -L
/XXX/libcurl/curl-7.15.9-ssl098/lib -lcurl
-L/XXX/libcurl/openssl-0.9.8o-install/lib -lssl -lcrypto -lz -g -o
multithread

Output Result :
 $: ./multithread
Thread 0, gets https://www.openssl.org/
operation reult : SSL connect error
Detailed Error code: Unknown SSL protocol error in connection to
www.openssl.org:443 err=-1, detail=5, errdetail=0, errnomsg=Resource
temporarily unavailable
Thread 0 terminated

-- 
Thanks and regards
K. Shalem  Raju,
9343217838 (m)

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2010-07-30