blob: 4c47d1626e17120d235fca11967d0e41bc22f3de [file] [log] [blame]
/*
This file is part of libmicrohttpd
Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file gnutls/init.c
* @brief gnutls-specific initialization routines
* @author Christian Grothoff
*/
#include "internal.h"
#include "init.h"
#ifdef MHD_HTTPS_REQUIRE_GCRYPT
#if defined(HTTPS_SUPPORT) && GCRYPT_VERSION_NUMBER < 0x010600
#if defined(MHD_USE_POSIX_THREADS)
GCRY_THREAD_OPTION_PTHREAD_IMPL;
#elif defined(MHD_W32_MUTEX_)
static int
gcry_w32_mutex_init (void **ppmtx)
{
*ppmtx = malloc (sizeof (MHD_mutex_));
if (NULL == *ppmtx)
return ENOMEM;
if (! MHD_mutex_init_ ((MHD_mutex_ *) *ppmtx))
{
free (*ppmtx);
*ppmtx = NULL;
return EPERM;
}
return 0;
}
static int
gcry_w32_mutex_destroy (void **ppmtx)
{
int res = (MHD_mutex_destroy_ ((MHD_mutex_ *) *ppmtx)) ? 0 : EINVAL;
free (*ppmtx);
return res;
}
static int
gcry_w32_mutex_lock (void **ppmtx)
{
return MHD_mutex_lock_ ((MHD_mutex_ *) *ppmtx) ? 0 : EINVAL;
}
static int
gcry_w32_mutex_unlock (void **ppmtx)
{
return MHD_mutex_unlock_ ((MHD_mutex_ *) *ppmtx) ? 0 : EINVAL;
}
static struct gcry_thread_cbs gcry_threads_w32 = {
(GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)),
NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy,
gcry_w32_mutex_lock, gcry_w32_mutex_unlock,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
#endif /* defined(MHD_W32_MUTEX_) */
#endif /* HTTPS_SUPPORT && GCRYPT_VERSION_NUMBER < 0x010600 */
#endif /* MHD_HTTPS_REQUIRE_GCRYPT */
#ifndef _AUTOINIT_FUNCS_ARE_SUPPORTED
/**
* Track global initialisation
*/
volatile int global_init_count = 0;
#ifdef MHD_MUTEX_STATIC_DEFN_INIT_
/**
* Global initialisation mutex
*/
MHD_MUTEX_STATIC_DEFN_INIT_ (global_init_mutex_);
#endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
#endif
/**
* Check whether global initialisation was performed
* and call initialiser if necessary.
*/
void
MHD_TLS_check_global_init_ (void)
{
#ifdef MHD_MUTEX_STATIC_DEFN_INIT_
MHD_mutex_lock_chk_ (&global_init_mutex_);
#endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
if (0 == global_init_count++)
MHD_init ();
#ifdef MHD_MUTEX_STATIC_DEFN_INIT_
MHD_mutex_unlock_chk_ (&global_init_mutex_);
#endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
}
/**
* Initialize do setup work.
*/
void
MHD_TLS_init (void)
{
#if defined(_WIN32) && ! defined(__CYGWIN__)
WSADATA wsd;
#endif /* _WIN32 && ! __CYGWIN__ */
#ifdef MHD_HTTPS_REQUIRE_GCRYPT
#if GCRYPT_VERSION_NUMBER < 0x010600
#if defined(MHD_USE_POSIX_THREADS)
if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
&gcry_threads_pthread))
MHD_PANIC (_ ("Failed to initialise multithreading in libgcrypt.\n"));
#elif defined(MHD_W32_MUTEX_)
if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
&gcry_threads_w32))
MHD_PANIC (_ ("Failed to initialise multithreading in libgcrypt.\n"));
#endif /* defined(MHD_W32_MUTEX_) */
gcry_check_version (NULL);
#else
if (NULL == gcry_check_version ("1.6.0"))
MHD_PANIC (_ (
"libgcrypt is too old. MHD was compiled for libgcrypt 1.6.0 or newer.\n"));
#endif
#endif /* MHD_HTTPS_REQUIRE_GCRYPT */
gnutls_global_init ();
}
void
MHD_TLS_fini (void)
{
gnutls_global_deinit ();
}
#ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
_SET_INIT_AND_DEINIT_FUNCS (MHD_TLS_init, MHD_TLS_fini);
#endif /* _AUTOINIT_FUNCS_ARE_SUPPORTED */