threaded-ssl.c
Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                  _   _ ____  _
00003  *  Project                     ___| | | |  _ \| |
00004  *                             / __| | | | |_) | |
00005  *                            | (__| |_| |  _ <| |___
00006  *                             \___|\___/|_| \_\_____|
00007  *
00008  * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
00009  *
00010  * This software is licensed as described in the file COPYING, which
00011  * you should have received as part of this distribution. The terms
00012  * are also available at https://curl.haxx.se/docs/copyright.html.
00013  *
00014  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
00015  * copies of the Software, and permit persons to whom the Software is
00016  * furnished to do so, under the terms of the COPYING file.
00017  *
00018  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
00019  * KIND, either express or implied.
00020  *
00021  ***************************************************************************/
00022 /* <DESC>
00023  * Show the required mutex callback setups for GnuTLS and OpenSSL when using
00024  * libcurl multi-threaded.
00025  * </DESC>
00026  */
00027 /* A multi-threaded example that uses pthreads and fetches 4 remote files at
00028  * once over HTTPS. The lock callbacks and stuff assume OpenSSL or GnuTLS
00029  * (libgcrypt) so far.
00030  *
00031  * OpenSSL docs for this:
00032  *   https://www.openssl.org/docs/crypto/threads.html
00033  * gcrypt docs for this:
00034  *   https://gnupg.org/documentation/manuals/gcrypt/Multi_002dThreading.html
00035  */
00036 
00037 #define USE_OPENSSL /* or USE_GNUTLS accordingly */
00038 
00039 #include <stdio.h>
00040 #include <pthread.h>
00041 #include <curl/curl.h>
00042 
00043 #define NUMT 4
00044 
00045 /* we have this global to let the callback get easy access to it */
00046 static pthread_mutex_t *lockarray;
00047 
00048 #ifdef USE_OPENSSL
00049 #include <openssl/crypto.h>
00050 static void lock_callback(int mode, int type, char *file, int line)
00051 {
00052   (void)file;
00053   (void)line;
00054   if(mode & CRYPTO_LOCK) {
00055     pthread_mutex_lock(&(lockarray[type]));
00056   }
00057   else {
00058     pthread_mutex_unlock(&(lockarray[type]));
00059   }
00060 }
00061 
00062 static unsigned long thread_id(void)
00063 {
00064   unsigned long ret;
00065 
00066   ret=(unsigned long)pthread_self();
00067   return ret;
00068 }
00069 
00070 static void init_locks(void)
00071 {
00072   int i;
00073 
00074   lockarray=(pthread_mutex_t *)OPENSSL_malloc(CRYPTO_num_locks() *
00075                                             sizeof(pthread_mutex_t));
00076   for(i=0; i<CRYPTO_num_locks(); i++) {
00077     pthread_mutex_init(&(lockarray[i]), NULL);
00078   }
00079 
00080   CRYPTO_set_id_callback((unsigned long (*)())thread_id);
00081   CRYPTO_set_locking_callback((void (*)())lock_callback);
00082 }
00083 
00084 static void kill_locks(void)
00085 {
00086   int i;
00087 
00088   CRYPTO_set_locking_callback(NULL);
00089   for(i=0; i<CRYPTO_num_locks(); i++)
00090     pthread_mutex_destroy(&(lockarray[i]));
00091 
00092   OPENSSL_free(lockarray);
00093 }
00094 #endif
00095 
00096 #ifdef USE_GNUTLS
00097 #include <gcrypt.h>
00098 #include <errno.h>
00099 
00100 GCRY_THREAD_OPTION_PTHREAD_IMPL;
00101 
00102 void init_locks(void)
00103 {
00104   gcry_control(GCRYCTL_SET_THREAD_CBS);
00105 }
00106 
00107 #define kill_locks()
00108 #endif
00109 
00110 /* List of URLs to fetch.*/
00111 const char * const urls[]= {
00112   "https://www.example.com/",
00113   "https://www2.example.com/",
00114   "https://www3.example.com/",
00115   "https://www4.example.com/",
00116 };
00117 
00118 static void *pull_one_url(void *url)
00119 {
00120   CURL *curl;
00121 
00122   curl = curl_easy_init();
00123   curl_easy_setopt(curl, CURLOPT_URL, url);
00124   /* this example doesn't verify the server's certificate, which means we
00125      might be downloading stuff from an impostor */
00126   curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
00127   curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
00128   curl_easy_perform(curl); /* ignores error */
00129   curl_easy_cleanup(curl);
00130 
00131   return NULL;
00132 }
00133 
00134 int main(int argc, char **argv)
00135 {
00136   pthread_t tid[NUMT];
00137   int i;
00138   int error;
00139   (void)argc; /* we don't use any arguments in this example */
00140   (void)argv;
00141 
00142   /* Must initialize libcurl before any threads are started */
00143   curl_global_init(CURL_GLOBAL_ALL);
00144 
00145   init_locks();
00146 
00147   for(i=0; i< NUMT; i++) {
00148     error = pthread_create(&tid[i],
00149                            NULL, /* default attributes please */
00150                            pull_one_url,
00151                            (void *)urls[i]);
00152     if(0 != error)
00153       fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error);
00154     else
00155       fprintf(stderr, "Thread %d, gets %s\n", i, urls[i]);
00156   }
00157 
00158   /* now wait for all threads to terminate */
00159   for(i=0; i< NUMT; i++) {
00160     error = pthread_join(tid[i], NULL);
00161     fprintf(stderr, "Thread %d terminated\n", i);
00162   }
00163 
00164   kill_locks();
00165 
00166   return 0;
00167 }


rc_visard_driver
Author(s): Heiko Hirschmueller , Christian Emmerich , Felix Ruess
autogenerated on Thu Jun 6 2019 20:43:06