You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

156 lines
3.7KB

  1. /*
  2. * Copyright (c) 2007 The Libav Project
  3. *
  4. * This file is part of Libav.
  5. *
  6. * Libav is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * Libav is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with Libav; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #include "network.h"
  21. #include "libavcodec/internal.h"
  22. #define THREADS (HAVE_PTHREADS || (defined(WIN32) && !defined(__MINGW32CE__)))
  23. #if THREADS
  24. #if HAVE_PTHREADS
  25. #include <pthread.h>
  26. #else
  27. #include "libavcodec/w32pthreads.h"
  28. #endif
  29. #endif
  30. #if CONFIG_OPENSSL
  31. #include <openssl/ssl.h>
  32. static int openssl_init;
  33. #if THREADS
  34. #include <openssl/crypto.h>
  35. #include "libavutil/avutil.h"
  36. pthread_mutex_t *openssl_mutexes;
  37. static void openssl_lock(int mode, int type, const char *file, int line)
  38. {
  39. if (mode & CRYPTO_LOCK)
  40. pthread_mutex_lock(&openssl_mutexes[type]);
  41. else
  42. pthread_mutex_unlock(&openssl_mutexes[type]);
  43. }
  44. #ifndef WIN32
  45. static unsigned long openssl_thread_id(void)
  46. {
  47. return (intptr_t) pthread_self();
  48. }
  49. #endif
  50. #endif
  51. #endif
  52. void ff_tls_init(void)
  53. {
  54. avpriv_lock_avformat();
  55. #if CONFIG_OPENSSL
  56. if (!openssl_init) {
  57. SSL_library_init();
  58. SSL_load_error_strings();
  59. #if THREADS
  60. if (!CRYPTO_get_locking_callback()) {
  61. int i;
  62. openssl_mutexes = av_malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks());
  63. for (i = 0; i < CRYPTO_num_locks(); i++)
  64. pthread_mutex_init(&openssl_mutexes[i], NULL);
  65. CRYPTO_set_locking_callback(openssl_lock);
  66. #ifndef WIN32
  67. CRYPTO_set_id_callback(openssl_thread_id);
  68. #endif
  69. }
  70. #endif
  71. }
  72. openssl_init++;
  73. #endif
  74. avpriv_unlock_avformat();
  75. }
  76. void ff_tls_deinit(void)
  77. {
  78. avpriv_lock_avformat();
  79. #if CONFIG_OPENSSL
  80. openssl_init--;
  81. if (!openssl_init) {
  82. #if THREADS
  83. if (CRYPTO_get_locking_callback() == openssl_lock) {
  84. int i;
  85. CRYPTO_set_locking_callback(NULL);
  86. for (i = 0; i < CRYPTO_num_locks(); i++)
  87. pthread_mutex_destroy(&openssl_mutexes[i]);
  88. av_free(openssl_mutexes);
  89. }
  90. #endif
  91. }
  92. #endif
  93. avpriv_unlock_avformat();
  94. }
  95. int ff_network_init(void)
  96. {
  97. #if HAVE_WINSOCK2_H
  98. WSADATA wsaData;
  99. if (WSAStartup(MAKEWORD(1,1), &wsaData))
  100. return 0;
  101. #endif
  102. return 1;
  103. }
  104. int ff_network_wait_fd(int fd, int write)
  105. {
  106. int ev = write ? POLLOUT : POLLIN;
  107. struct pollfd p = { .fd = fd, .events = ev, .revents = 0 };
  108. int ret;
  109. ret = poll(&p, 1, 100);
  110. return ret < 0 ? ff_neterrno() : p.revents & (ev | POLLERR | POLLHUP) ? 0 : AVERROR(EAGAIN);
  111. }
  112. void ff_network_close(void)
  113. {
  114. #if HAVE_WINSOCK2_H
  115. WSACleanup();
  116. #endif
  117. }
  118. #if HAVE_WINSOCK2_H
  119. int ff_neterrno(void)
  120. {
  121. int err = WSAGetLastError();
  122. switch (err) {
  123. case WSAEWOULDBLOCK:
  124. return AVERROR(EAGAIN);
  125. case WSAEINTR:
  126. return AVERROR(EINTR);
  127. }
  128. return -err;
  129. }
  130. #endif
  131. int ff_is_multicast_address(struct sockaddr *addr)
  132. {
  133. if (addr->sa_family == AF_INET) {
  134. return IN_MULTICAST(ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr));
  135. }
  136. #if HAVE_STRUCT_SOCKADDR_IN6
  137. if (addr->sa_family == AF_INET6) {
  138. return IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)addr)->sin6_addr);
  139. }
  140. #endif
  141. return 0;
  142. }