diff --git a/libavformat/network.c b/libavformat/network.c index 57a5b418e7..2d0503168e 100644 --- a/libavformat/network.c +++ b/libavformat/network.c @@ -20,111 +20,34 @@ #include #include "network.h" +#include "tls.h" #include "url.h" #include "libavcodec/internal.h" #include "libavutil/avutil.h" #include "libavutil/mem.h" #include "libavutil/time.h" -#if HAVE_THREADS -#if HAVE_PTHREADS -#include -#elif HAVE_OS2THREADS -#include "compat/os2threads.h" -#else -#include "compat/w32pthreads.h" -#endif -#endif - -#if CONFIG_OPENSSL -#include -static int openssl_init; -#if HAVE_THREADS -#include -pthread_mutex_t *openssl_mutexes; -static void openssl_lock(int mode, int type, const char *file, int line) -{ - if (mode & CRYPTO_LOCK) - pthread_mutex_lock(&openssl_mutexes[type]); - else - pthread_mutex_unlock(&openssl_mutexes[type]); -} -#if !defined(WIN32) && OPENSSL_VERSION_NUMBER < 0x10000000 -static unsigned long openssl_thread_id(void) -{ - return (intptr_t) pthread_self(); -} -#endif -#endif -#endif -#if CONFIG_GNUTLS -#include -#if HAVE_THREADS && GNUTLS_VERSION_NUMBER <= 0x020b00 -#include -#include -GCRY_THREAD_OPTION_PTHREAD_IMPL; -#endif -#endif - int ff_tls_init(void) { - avpriv_lock_avformat(); -#if CONFIG_OPENSSL - if (!openssl_init) { - SSL_library_init(); - SSL_load_error_strings(); -#if HAVE_THREADS - if (!CRYPTO_get_locking_callback()) { - int i; - openssl_mutexes = av_malloc_array(sizeof(pthread_mutex_t), CRYPTO_num_locks()); - if (!openssl_mutexes) { - avpriv_unlock_avformat(); - return AVERROR(ENOMEM); - } - for (i = 0; i < CRYPTO_num_locks(); i++) - pthread_mutex_init(&openssl_mutexes[i], NULL); - CRYPTO_set_locking_callback(openssl_lock); -#if !defined(WIN32) && OPENSSL_VERSION_NUMBER < 0x10000000 - CRYPTO_set_id_callback(openssl_thread_id); + int ret; +#if CONFIG_TLS_OPENSSL_PROTOCOL + if ((ret = ff_openssl_init()) < 0) + return ret; #endif - } +#if CONFIG_TLS_GNUTLS_PROTOCOL + ff_gnutls_init(); #endif - } - openssl_init++; -#endif -#if CONFIG_GNUTLS -#if HAVE_THREADS && GNUTLS_VERSION_NUMBER < 0x020b00 - if (gcry_control(GCRYCTL_ANY_INITIALIZATION_P) == 0) - gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); -#endif - gnutls_global_init(); -#endif - avpriv_unlock_avformat(); - return 0; } void ff_tls_deinit(void) { - avpriv_lock_avformat(); -#if CONFIG_OPENSSL - openssl_init--; - if (!openssl_init) { -#if HAVE_THREADS - if (CRYPTO_get_locking_callback() == openssl_lock) { - int i; - CRYPTO_set_locking_callback(NULL); - for (i = 0; i < CRYPTO_num_locks(); i++) - pthread_mutex_destroy(&openssl_mutexes[i]); - av_free(openssl_mutexes); - } +#if CONFIG_TLS_OPENSSL_PROTOCOL + ff_openssl_deinit(); #endif - } +#if CONFIG_TLS_GNUTLS_PROTOCOL + ff_gnutls_deinit(); #endif -#if CONFIG_GNUTLS - gnutls_global_deinit(); -#endif - avpriv_unlock_avformat(); } int ff_network_inited_globally; diff --git a/libavformat/tls.h b/libavformat/tls.h index 445b1b5cef..558676fc8c 100644 --- a/libavformat/tls.h +++ b/libavformat/tls.h @@ -52,4 +52,10 @@ typedef struct TLSShared { int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AVDictionary **options); +void ff_gnutls_init(void); +void ff_gnutls_deinit(void); + +int ff_openssl_init(void); +void ff_openssl_deinit(void); + #endif /* AVFORMAT_TLS_H */ diff --git a/libavformat/tls_gnutls.c b/libavformat/tls_gnutls.c index 92a88c164f..b846bc4469 100644 --- a/libavformat/tls_gnutls.c +++ b/libavformat/tls_gnutls.c @@ -19,6 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include + #include #include @@ -28,10 +30,16 @@ #include "os_support.h" #include "url.h" #include "tls.h" +#include "libavcodec/internal.h" #include "libavutil/avstring.h" #include "libavutil/opt.h" #include "libavutil/parseutils.h" +#if HAVE_THREADS && GNUTLS_VERSION_NUMBER <= 0x020b00 +#include +GCRY_THREAD_OPTION_PTHREAD_IMPL; +#endif + typedef struct TLSContext { const AVClass *class; TLSShared tls_shared; @@ -40,6 +48,24 @@ typedef struct TLSContext { int need_shutdown; } TLSContext; +void ff_gnutls_init(void) +{ + avpriv_lock_avformat(); +#if HAVE_THREADS && GNUTLS_VERSION_NUMBER < 0x020b00 + if (gcry_control(GCRYCTL_ANY_INITIALIZATION_P) == 0) + gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); +#endif + gnutls_global_init(); + avpriv_unlock_avformat(); +} + +void ff_gnutls_deinit(void) +{ + avpriv_lock_avformat(); + gnutls_global_deinit(); + avpriv_unlock_avformat(); +} + static int print_tls_error(URLContext *h, int ret) { switch (ret) { @@ -67,7 +93,7 @@ static int tls_close(URLContext *h) gnutls_certificate_free_credentials(c->cred); if (c->tls_shared.tcp) ffurl_close(c->tls_shared.tcp); - ff_tls_deinit(); + ff_gnutls_deinit(); return 0; } @@ -103,8 +129,7 @@ static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **op TLSShared *c = &p->tls_shared; int ret; - if ((ret = ff_tls_init()) < 0) - return ret; + ff_gnutls_init(); if ((ret = ff_tls_open_underlying(c, h, uri, options)) < 0) goto fail; diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c index 3dbd4f4e86..636d4ee910 100644 --- a/libavformat/tls_openssl.c +++ b/libavformat/tls_openssl.c @@ -25,14 +25,19 @@ #include "os_support.h" #include "url.h" #include "tls.h" +#include "libavcodec/internal.h" #include "libavutil/avstring.h" +#include "libavutil/avutil.h" #include "libavutil/opt.h" #include "libavutil/parseutils.h" +#include "libavutil/thread.h" #include #include #include +static int openssl_init; + typedef struct TLSContext { const AVClass *class; TLSShared tls_shared; @@ -40,6 +45,72 @@ typedef struct TLSContext { SSL *ssl; } TLSContext; +#if HAVE_THREADS +#include +pthread_mutex_t *openssl_mutexes; +static void openssl_lock(int mode, int type, const char *file, int line) +{ + if (mode & CRYPTO_LOCK) + pthread_mutex_lock(&openssl_mutexes[type]); + else + pthread_mutex_unlock(&openssl_mutexes[type]); +} +#if !defined(WIN32) && OPENSSL_VERSION_NUMBER < 0x10000000 +static unsigned long openssl_thread_id(void) +{ + return (intptr_t) pthread_self(); +} +#endif +#endif + +int ff_openssl_init(void) +{ + avpriv_lock_avformat(); + if (!openssl_init) { + SSL_library_init(); + SSL_load_error_strings(); +#if HAVE_THREADS + if (!CRYPTO_get_locking_callback()) { + int i; + openssl_mutexes = av_malloc_array(sizeof(pthread_mutex_t), CRYPTO_num_locks()); + if (!openssl_mutexes) { + avpriv_unlock_avformat(); + return AVERROR(ENOMEM); + } + + for (i = 0; i < CRYPTO_num_locks(); i++) + pthread_mutex_init(&openssl_mutexes[i], NULL); + CRYPTO_set_locking_callback(openssl_lock); +#if !defined(WIN32) && OPENSSL_VERSION_NUMBER < 0x10000000 + CRYPTO_set_id_callback(openssl_thread_id); +#endif + } +#endif + } + openssl_init++; + avpriv_unlock_avformat(); + + return 0; +} + +void ff_openssl_deinit(void) +{ + avpriv_lock_avformat(); + openssl_init--; + if (!openssl_init) { +#if HAVE_THREADS + if (CRYPTO_get_locking_callback() == openssl_lock) { + int i; + CRYPTO_set_locking_callback(NULL); + for (i = 0; i < CRYPTO_num_locks(); i++) + pthread_mutex_destroy(&openssl_mutexes[i]); + av_free(openssl_mutexes); + } +#endif + } + avpriv_unlock_avformat(); +} + static int print_tls_error(URLContext *h, int ret) { av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL)); @@ -57,7 +128,7 @@ static int tls_close(URLContext *h) SSL_CTX_free(c->ctx); if (c->tls_shared.tcp) ffurl_close(c->tls_shared.tcp); - ff_tls_deinit(); + ff_openssl_deinit(); return 0; } @@ -131,7 +202,7 @@ static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **op BIO *bio; int ret; - if ((ret = ff_tls_init()) < 0) + if ((ret = ff_openssl_init()) < 0) return ret; if ((ret = ff_tls_open_underlying(c, h, uri, options)) < 0)