• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavformat/network.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2007 The Libav Project
00003  *
00004  * This file is part of Libav.
00005  *
00006  * Libav is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * Libav is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with Libav; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00019  */
00020 
00021 #include "libavutil/avutil.h"
00022 #include "network.h"
00023 #include "libavcodec/internal.h"
00024 
00025 #define THREADS (HAVE_PTHREADS || (defined(WIN32) && !defined(__MINGW32CE__)))
00026 
00027 #if THREADS
00028 #if HAVE_PTHREADS
00029 #include <pthread.h>
00030 #else
00031 #include "libavcodec/w32pthreads.h"
00032 #endif
00033 #endif
00034 
00035 #if CONFIG_OPENSSL
00036 #include <openssl/ssl.h>
00037 static int openssl_init;
00038 #if THREADS
00039 #include <openssl/crypto.h>
00040 #include "libavutil/avutil.h"
00041 pthread_mutex_t *openssl_mutexes;
00042 static void openssl_lock(int mode, int type, const char *file, int line)
00043 {
00044     if (mode & CRYPTO_LOCK)
00045         pthread_mutex_lock(&openssl_mutexes[type]);
00046     else
00047         pthread_mutex_unlock(&openssl_mutexes[type]);
00048 }
00049 #if !defined(WIN32) && OPENSSL_VERSION_NUMBER < 0x10000000
00050 static unsigned long openssl_thread_id(void)
00051 {
00052     return (intptr_t) pthread_self();
00053 }
00054 #endif
00055 #endif
00056 #endif
00057 #if CONFIG_GNUTLS
00058 #include <gnutls/gnutls.h>
00059 #if THREADS && GNUTLS_VERSION_NUMBER <= 0x020b00
00060 #include <gcrypt.h>
00061 #include <errno.h>
00062 #undef malloc
00063 #undef free
00064 GCRY_THREAD_OPTION_PTHREAD_IMPL;
00065 #endif
00066 #endif
00067 
00068 void ff_tls_init(void)
00069 {
00070     avpriv_lock_avformat();
00071 #if CONFIG_OPENSSL
00072     if (!openssl_init) {
00073         SSL_library_init();
00074         SSL_load_error_strings();
00075 #if THREADS
00076         if (!CRYPTO_get_locking_callback()) {
00077             int i;
00078             openssl_mutexes = av_malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks());
00079             for (i = 0; i < CRYPTO_num_locks(); i++)
00080                 pthread_mutex_init(&openssl_mutexes[i], NULL);
00081             CRYPTO_set_locking_callback(openssl_lock);
00082 #if !defined(WIN32) && OPENSSL_VERSION_NUMBER < 0x10000000
00083             CRYPTO_set_id_callback(openssl_thread_id);
00084 #endif
00085         }
00086 #endif
00087     }
00088     openssl_init++;
00089 #endif
00090 #if CONFIG_GNUTLS
00091 #if THREADS && GNUTLS_VERSION_NUMBER < 0x020b00
00092     if (gcry_control(GCRYCTL_ANY_INITIALIZATION_P) == 0)
00093         gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
00094 #endif
00095     gnutls_global_init();
00096 #endif
00097     avpriv_unlock_avformat();
00098 }
00099 
00100 void ff_tls_deinit(void)
00101 {
00102     avpriv_lock_avformat();
00103 #if CONFIG_OPENSSL
00104     openssl_init--;
00105     if (!openssl_init) {
00106 #if THREADS
00107         if (CRYPTO_get_locking_callback() == openssl_lock) {
00108             int i;
00109             CRYPTO_set_locking_callback(NULL);
00110             for (i = 0; i < CRYPTO_num_locks(); i++)
00111                 pthread_mutex_destroy(&openssl_mutexes[i]);
00112             av_free(openssl_mutexes);
00113         }
00114 #endif
00115     }
00116 #endif
00117 #if CONFIG_GNUTLS
00118     gnutls_global_deinit();
00119 #endif
00120     avpriv_unlock_avformat();
00121 }
00122 
00123 int ff_network_inited_globally;
00124 
00125 int ff_network_init(void)
00126 {
00127 #if HAVE_WINSOCK2_H
00128     WSADATA wsaData;
00129 #endif
00130 
00131     if (!ff_network_inited_globally)
00132         av_log(NULL, AV_LOG_WARNING, "Using network protocols without global "
00133                                      "network initialization. Please use "
00134                                      "avformat_network_init(), this will "
00135                                      "become mandatory later.\n");
00136 #if HAVE_WINSOCK2_H
00137     if (WSAStartup(MAKEWORD(1,1), &wsaData))
00138         return 0;
00139 #endif
00140     return 1;
00141 }
00142 
00143 int ff_network_wait_fd(int fd, int write)
00144 {
00145     int ev = write ? POLLOUT : POLLIN;
00146     struct pollfd p = { .fd = fd, .events = ev, .revents = 0 };
00147     int ret;
00148     ret = poll(&p, 1, 100);
00149     return ret < 0 ? ff_neterrno() : p.revents & (ev | POLLERR | POLLHUP) ? 0 : AVERROR(EAGAIN);
00150 }
00151 
00152 void ff_network_close(void)
00153 {
00154 #if HAVE_WINSOCK2_H
00155     WSACleanup();
00156 #endif
00157 }
00158 
00159 #if HAVE_WINSOCK2_H
00160 int ff_neterrno(void)
00161 {
00162     int err = WSAGetLastError();
00163     switch (err) {
00164     case WSAEWOULDBLOCK:
00165         return AVERROR(EAGAIN);
00166     case WSAEINTR:
00167         return AVERROR(EINTR);
00168     }
00169     return -err;
00170 }
00171 #endif
00172 
00173 int ff_is_multicast_address(struct sockaddr *addr)
00174 {
00175     if (addr->sa_family == AF_INET) {
00176         return IN_MULTICAST(ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr));
00177     }
00178 #if HAVE_STRUCT_SOCKADDR_IN6
00179     if (addr->sa_family == AF_INET6) {
00180         return IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)addr)->sin6_addr);
00181     }
00182 #endif
00183 
00184     return 0;
00185 }
00186 
Generated on Fri Feb 1 2013 14:34:53 for FFmpeg by doxygen 1.7.1