FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
network.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2007 The FFmpeg Project
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg 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  * FFmpeg 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 FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <fcntl.h>
22 #include "network.h"
23 #include "tls.h"
24 #include "url.h"
25 #include "libavcodec/internal.h"
26 #include "libavutil/avutil.h"
27 #include "libavutil/avassert.h"
28 #include "libavutil/mem.h"
29 #include "libavutil/time.h"
30 
31 int ff_tls_init(void)
32 {
33 #if CONFIG_TLS_PROTOCOL
34 #if CONFIG_OPENSSL
35  int ret;
36  if ((ret = ff_openssl_init()) < 0)
37  return ret;
38 #endif
39 #if CONFIG_GNUTLS
41 #endif
42 #endif
43  return 0;
44 }
45 
46 void ff_tls_deinit(void)
47 {
48 #if CONFIG_TLS_PROTOCOL
49 #if CONFIG_OPENSSL
51 #endif
52 #if CONFIG_GNUTLS
54 #endif
55 #endif
56 }
57 
58 int ff_network_init(void)
59 {
60 #if HAVE_WINSOCK2_H
61  WSADATA wsaData;
62 
63  if (WSAStartup(MAKEWORD(1,1), &wsaData))
64  return 0;
65 #endif
66  return 1;
67 }
68 
69 int ff_network_wait_fd(int fd, int write)
70 {
71  int ev = write ? POLLOUT : POLLIN;
72  struct pollfd p = { .fd = fd, .events = ev, .revents = 0 };
73  int ret;
74  ret = poll(&p, 1, POLLING_TIME);
75  return ret < 0 ? ff_neterrno() : p.revents & (ev | POLLERR | POLLHUP) ? 0 : AVERROR(EAGAIN);
76 }
77 
78 int ff_network_wait_fd_timeout(int fd, int write, int64_t timeout, AVIOInterruptCB *int_cb)
79 {
80  int ret;
81  int64_t wait_start = 0;
82 
83  while (1) {
84  if (ff_check_interrupt(int_cb))
85  return AVERROR_EXIT;
86  ret = ff_network_wait_fd(fd, write);
87  if (ret != AVERROR(EAGAIN))
88  return ret;
89  if (timeout > 0) {
90  if (!wait_start)
91  wait_start = av_gettime_relative();
92  else if (av_gettime_relative() - wait_start > timeout)
93  return AVERROR(ETIMEDOUT);
94  }
95  }
96 }
97 
99 {
100  int64_t wait_start = av_gettime_relative();
101 
102  while (1) {
103  int64_t time_left;
104 
105  if (ff_check_interrupt(int_cb))
106  return AVERROR_EXIT;
107 
108  time_left = timeout - (av_gettime_relative() - wait_start);
109  if (time_left <= 0)
110  return AVERROR(ETIMEDOUT);
111 
112  av_usleep(FFMIN(time_left, POLLING_TIME * 1000));
113  }
114 }
115 
117 {
118 #if HAVE_WINSOCK2_H
119  WSACleanup();
120 #endif
121 }
122 
123 #if HAVE_WINSOCK2_H
124 int ff_neterrno(void)
125 {
126  int err = WSAGetLastError();
127  switch (err) {
128  case WSAEWOULDBLOCK:
129  return AVERROR(EAGAIN);
130  case WSAEINTR:
131  return AVERROR(EINTR);
132  case WSAEPROTONOSUPPORT:
133  return AVERROR(EPROTONOSUPPORT);
134  case WSAETIMEDOUT:
135  return AVERROR(ETIMEDOUT);
136  case WSAECONNREFUSED:
137  return AVERROR(ECONNREFUSED);
138  case WSAEINPROGRESS:
139  return AVERROR(EINPROGRESS);
140  }
141  return -err;
142 }
143 #endif
144 
145 int ff_is_multicast_address(struct sockaddr *addr)
146 {
147  if (addr->sa_family == AF_INET) {
148  return IN_MULTICAST(ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr));
149  }
150 #if HAVE_STRUCT_SOCKADDR_IN6
151  if (addr->sa_family == AF_INET6) {
152  return IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)addr)->sin6_addr);
153  }
154 #endif
155 
156  return 0;
157 }
158 
159 static int ff_poll_interrupt(struct pollfd *p, nfds_t nfds, int timeout,
161 {
162  int runs = timeout / POLLING_TIME;
163  int ret = 0;
164 
165  do {
166  if (ff_check_interrupt(cb))
167  return AVERROR_EXIT;
168  ret = poll(p, nfds, POLLING_TIME);
169  if (ret != 0) {
170  if (ret < 0)
171  ret = ff_neterrno();
172  if (ret == AVERROR(EINTR))
173  continue;
174  break;
175  }
176  } while (timeout <= 0 || runs-- > 0);
177 
178  if (!ret)
179  return AVERROR(ETIMEDOUT);
180  return ret;
181 }
182 
183 int ff_socket(int af, int type, int proto)
184 {
185  int fd;
186 
187 #ifdef SOCK_CLOEXEC
188  fd = socket(af, type | SOCK_CLOEXEC, proto);
189  if (fd == -1 && errno == EINVAL)
190 #endif
191  {
192  fd = socket(af, type, proto);
193 #if HAVE_FCNTL
194  if (fd != -1) {
195  if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
196  av_log(NULL, AV_LOG_DEBUG, "Failed to set close on exec\n");
197  }
198 #endif
199  }
200 #ifdef SO_NOSIGPIPE
201  if (fd != -1) {
202  if (setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &(int){1}, sizeof(int))) {
203  av_log(NULL, AV_LOG_WARNING, "setsockopt(SO_NOSIGPIPE) failed\n");
204  }
205  }
206 #endif
207  return fd;
208 }
209 
210 int ff_listen(int fd, const struct sockaddr *addr,
211  socklen_t addrlen)
212 {
213  int ret;
214  int reuse = 1;
215  if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))) {
216  av_log(NULL, AV_LOG_WARNING, "setsockopt(SO_REUSEADDR) failed\n");
217  }
218  ret = bind(fd, addr, addrlen);
219  if (ret)
220  return ff_neterrno();
221 
222  ret = listen(fd, 1);
223  if (ret)
224  return ff_neterrno();
225  return ret;
226 }
227 
228 int ff_accept(int fd, int timeout, URLContext *h)
229 {
230  int ret;
231  struct pollfd lp = { fd, POLLIN, 0 };
232 
233  ret = ff_poll_interrupt(&lp, 1, timeout, &h->interrupt_callback);
234  if (ret < 0)
235  return ret;
236 
237  ret = accept(fd, NULL, NULL);
238  if (ret < 0)
239  return ff_neterrno();
240  if (ff_socket_nonblock(ret, 1) < 0)
241  av_log(NULL, AV_LOG_DEBUG, "ff_socket_nonblock failed\n");
242 
243  return ret;
244 }
245 
246 int ff_listen_bind(int fd, const struct sockaddr *addr,
247  socklen_t addrlen, int timeout, URLContext *h)
248 {
249  int ret;
250  if ((ret = ff_listen(fd, addr, addrlen)) < 0)
251  return ret;
252  if ((ret = ff_accept(fd, timeout, h)) < 0)
253  return ret;
254  closesocket(fd);
255  return ret;
256 }
257 
258 int ff_listen_connect(int fd, const struct sockaddr *addr,
259  socklen_t addrlen, int timeout, URLContext *h,
260  int will_try_next)
261 {
262  struct pollfd p = {fd, POLLOUT, 0};
263  int ret;
264  socklen_t optlen;
265 
266  if (ff_socket_nonblock(fd, 1) < 0)
267  av_log(NULL, AV_LOG_DEBUG, "ff_socket_nonblock failed\n");
268 
269  while ((ret = connect(fd, addr, addrlen))) {
270  ret = ff_neterrno();
271  switch (ret) {
272  case AVERROR(EINTR):
274  return AVERROR_EXIT;
275  continue;
276  case AVERROR(EINPROGRESS):
277  case AVERROR(EAGAIN):
278  ret = ff_poll_interrupt(&p, 1, timeout, &h->interrupt_callback);
279  if (ret < 0)
280  return ret;
281  optlen = sizeof(ret);
282  if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen))
283  ret = AVUNERROR(ff_neterrno());
284  if (ret != 0) {
285  char errbuf[100];
286  ret = AVERROR(ret);
287  av_strerror(ret, errbuf, sizeof(errbuf));
288  if (will_try_next)
290  "Connection to %s failed (%s), trying next address\n",
291  h->filename, errbuf);
292  else
293  av_log(h, AV_LOG_ERROR, "Connection to %s failed: %s\n",
294  h->filename, errbuf);
295  }
296  default:
297  return ret;
298  }
299  }
300  return ret;
301 }
302 
303 static void interleave_addrinfo(struct addrinfo *base)
304 {
305  struct addrinfo **next = &base->ai_next;
306  while (*next) {
307  struct addrinfo *cur = *next;
308  // Iterate forward until we find an entry of a different family.
309  if (cur->ai_family == base->ai_family) {
310  next = &cur->ai_next;
311  continue;
312  }
313  if (cur == base->ai_next) {
314  // If the first one following base is of a different family, just
315  // move base forward one step and continue.
316  base = cur;
317  next = &base->ai_next;
318  continue;
319  }
320  // Unchain cur from the rest of the list from its current spot.
321  *next = cur->ai_next;
322  // Hook in cur directly after base.
323  cur->ai_next = base->ai_next;
324  base->ai_next = cur;
325  // Restart with a new base. We know that before moving the cur element,
326  // everything between the previous base and cur had the same family,
327  // different from cur->ai_family. Therefore, we can keep next pointing
328  // where it was, and continue from there with base at the one after
329  // cur.
330  base = cur->ai_next;
331  }
332 }
333 
334 static void print_address_list(void *ctx, const struct addrinfo *addr,
335  const char *title)
336 {
337  char hostbuf[100], portbuf[20];
338  av_log(ctx, AV_LOG_DEBUG, "%s:\n", title);
339  while (addr) {
340  getnameinfo(addr->ai_addr, addr->ai_addrlen,
341  hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf),
343  av_log(ctx, AV_LOG_DEBUG, "Address %s port %s\n", hostbuf, portbuf);
344  addr = addr->ai_next;
345  }
346 }
347 
349  int fd;
350  int64_t deadline_us;
351  struct addrinfo *addr;
352 };
353 
354 // Returns < 0 on error, 0 on successfully started connection attempt,
355 // > 0 for a connection that succeeded already.
356 static int start_connect_attempt(struct ConnectionAttempt *attempt,
357  struct addrinfo **ptr, int timeout_ms,
358  URLContext *h,
359  void (*customize_fd)(void *, int), void *customize_ctx)
360 {
361  struct addrinfo *ai = *ptr;
362  int ret;
363 
364  *ptr = ai->ai_next;
365 
366  attempt->fd = ff_socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
367  if (attempt->fd < 0)
368  return ff_neterrno();
369  attempt->deadline_us = av_gettime_relative() + timeout_ms * 1000;
370  attempt->addr = ai;
371 
372  ff_socket_nonblock(attempt->fd, 1);
373 
374  if (customize_fd)
375  customize_fd(customize_ctx, attempt->fd);
376 
377  while ((ret = connect(attempt->fd, ai->ai_addr, ai->ai_addrlen))) {
378  ret = ff_neterrno();
379  switch (ret) {
380  case AVERROR(EINTR):
382  closesocket(attempt->fd);
383  attempt->fd = -1;
384  return AVERROR_EXIT;
385  }
386  continue;
387  case AVERROR(EINPROGRESS):
388  case AVERROR(EAGAIN):
389  return 0;
390  default:
391  closesocket(attempt->fd);
392  attempt->fd = -1;
393  return ret;
394  }
395  }
396  return 1;
397 }
398 
399 // Try a new connection to another address after 200 ms, as suggested in
400 // RFC 8305 (or sooner if an earlier attempt fails).
401 #define NEXT_ATTEMPT_DELAY_MS 200
402 
403 int ff_connect_parallel(struct addrinfo *addrs, int timeout_ms_per_address,
404  int parallel, URLContext *h, int *fd,
405  void (*customize_fd)(void *, int), void *customize_ctx)
406 {
407  struct ConnectionAttempt attempts[3];
408  struct pollfd pfd[3];
409  int nb_attempts = 0, i, j;
410  int64_t next_attempt_us = av_gettime_relative(), next_deadline_us;
411  int last_err = AVERROR(EIO);
412  socklen_t optlen;
413  char errbuf[100], hostbuf[100], portbuf[20];
414 
415  if (parallel > FF_ARRAY_ELEMS(attempts))
416  parallel = FF_ARRAY_ELEMS(attempts);
417 
418  print_address_list(h, addrs, "Original list of addresses");
419  // This mutates the list, but the head of the list is still the same
420  // element, so the caller, who owns the list, doesn't need to get
421  // an updated pointer.
422  interleave_addrinfo(addrs);
423  print_address_list(h, addrs, "Interleaved list of addresses");
424 
425  while (nb_attempts > 0 || addrs) {
426  // Start a new connection attempt, if possible.
427  if (nb_attempts < parallel && addrs) {
428  getnameinfo(addrs->ai_addr, addrs->ai_addrlen,
429  hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf),
431  av_log(h, AV_LOG_VERBOSE, "Starting connection attempt to %s port %s\n",
432  hostbuf, portbuf);
433  last_err = start_connect_attempt(&attempts[nb_attempts], &addrs,
434  timeout_ms_per_address, h,
435  customize_fd, customize_ctx);
436  if (last_err < 0) {
437  av_strerror(last_err, errbuf, sizeof(errbuf));
438  av_log(h, AV_LOG_VERBOSE, "Connected attempt failed: %s\n",
439  errbuf);
440  continue;
441  }
442  if (last_err > 0) {
443  for (i = 0; i < nb_attempts; i++)
444  closesocket(attempts[i].fd);
445  *fd = attempts[nb_attempts].fd;
446  return 0;
447  }
448  pfd[nb_attempts].fd = attempts[nb_attempts].fd;
449  pfd[nb_attempts].events = POLLOUT;
450  next_attempt_us = av_gettime_relative() + NEXT_ATTEMPT_DELAY_MS * 1000;
451  nb_attempts++;
452  }
453 
454  av_assert0(nb_attempts > 0);
455  // The connection attempts are sorted from oldest to newest, so the
456  // first one will have the earliest deadline.
457  next_deadline_us = attempts[0].deadline_us;
458  // If we can start another attempt in parallel, wait until that time.
459  if (nb_attempts < parallel && addrs)
460  next_deadline_us = FFMIN(next_deadline_us, next_attempt_us);
461  last_err = ff_poll_interrupt(pfd, nb_attempts,
462  (next_deadline_us - av_gettime_relative())/1000,
463  &h->interrupt_callback);
464  if (last_err < 0 && last_err != AVERROR(ETIMEDOUT))
465  break;
466 
467  // Check the status from the poll output.
468  for (i = 0; i < nb_attempts; i++) {
469  last_err = 0;
470  if (pfd[i].revents) {
471  // Some sort of action for this socket, check its status (either
472  // a successful connection or an error).
473  optlen = sizeof(last_err);
474  if (getsockopt(attempts[i].fd, SOL_SOCKET, SO_ERROR, &last_err, &optlen))
475  last_err = ff_neterrno();
476  else if (last_err != 0)
477  last_err = AVERROR(last_err);
478  if (last_err == 0) {
479  // Everything is ok, we seem to have a successful
480  // connection. Close other sockets and return this one.
481  for (j = 0; j < nb_attempts; j++)
482  if (j != i)
483  closesocket(attempts[j].fd);
484  *fd = attempts[i].fd;
485  getnameinfo(attempts[i].addr->ai_addr, attempts[i].addr->ai_addrlen,
486  hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf),
488  av_log(h, AV_LOG_VERBOSE, "Successfully connected to %s port %s\n",
489  hostbuf, portbuf);
490  return 0;
491  }
492  }
493  if (attempts[i].deadline_us < av_gettime_relative() && !last_err)
494  last_err = AVERROR(ETIMEDOUT);
495  if (!last_err)
496  continue;
497  // Error (or timeout) for this socket; close the socket and remove
498  // it from the attempts/pfd arrays, to let a new attempt start
499  // directly.
500  getnameinfo(attempts[i].addr->ai_addr, attempts[i].addr->ai_addrlen,
501  hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf),
503  av_strerror(last_err, errbuf, sizeof(errbuf));
504  av_log(h, AV_LOG_VERBOSE, "Connection attempt to %s port %s "
505  "failed: %s\n", hostbuf, portbuf, errbuf);
506  closesocket(attempts[i].fd);
507  memmove(&attempts[i], &attempts[i + 1],
508  (nb_attempts - i - 1) * sizeof(*attempts));
509  memmove(&pfd[i], &pfd[i + 1],
510  (nb_attempts - i - 1) * sizeof(*pfd));
511  i--;
512  nb_attempts--;
513  }
514  }
515  for (i = 0; i < nb_attempts; i++)
516  closesocket(attempts[i].fd);
517  if (last_err >= 0)
518  last_err = AVERROR(ECONNREFUSED);
519  if (last_err != AVERROR_EXIT) {
520  av_strerror(last_err, errbuf, sizeof(errbuf));
521  av_log(h, AV_LOG_ERROR, "Connection to %s failed: %s\n",
522  h->filename, errbuf);
523  }
524  return last_err;
525 }
526 
527 static int match_host_pattern(const char *pattern, const char *hostname)
528 {
529  int len_p, len_h;
530  if (!strcmp(pattern, "*"))
531  return 1;
532  // Skip a possible *. at the start of the pattern
533  if (pattern[0] == '*')
534  pattern++;
535  if (pattern[0] == '.')
536  pattern++;
537  len_p = strlen(pattern);
538  len_h = strlen(hostname);
539  if (len_p > len_h)
540  return 0;
541  // Simply check if the end of hostname is equal to 'pattern'
542  if (!strcmp(pattern, &hostname[len_h - len_p])) {
543  if (len_h == len_p)
544  return 1; // Exact match
545  if (hostname[len_h - len_p - 1] == '.')
546  return 1; // The matched substring is a domain and not just a substring of a domain
547  }
548  return 0;
549 }
550 
551 int ff_http_match_no_proxy(const char *no_proxy, const char *hostname)
552 {
553  char *buf, *start;
554  int ret = 0;
555  if (!no_proxy)
556  return 0;
557  if (!hostname)
558  return 0;
559  buf = av_strdup(no_proxy);
560  if (!buf)
561  return 0;
562  start = buf;
563  while (start) {
564  char *sep, *next = NULL;
565  start += strspn(start, " ,");
566  sep = start + strcspn(start, " ,");
567  if (*sep) {
568  next = sep + 1;
569  *sep = '\0';
570  }
571  if (match_host_pattern(start, hostname)) {
572  ret = 1;
573  break;
574  }
575  start = next;
576  }
577  av_free(buf);
578  return ret;
579 }
580 
581 void ff_log_net_error(void *ctx, int level, const char* prefix)
582 {
583  char errbuf[100];
584  av_strerror(ff_neterrno(), errbuf, sizeof(errbuf));
585  av_log(ctx, level, "%s: %s\n", prefix, errbuf);
586 }
#define NULL
Definition: coverity.c:32
#define NI_NUMERICSERV
Definition: network.h:200
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
static void customize_fd(void *ctx, int fd)
Definition: tcp.c:73
Memory handling functions.
#define NEXT_ATTEMPT_DELAY_MS
Definition: network.c:401
static int match_host_pattern(const char *pattern, const char *hostname)
Definition: network.c:527
AVIOInterruptCB interrupt_callback
Definition: url.h:47
Convenience header that includes libavutil's core.
void ff_network_close(void)
Definition: network.c:116
int ff_tls_init(void)
Definition: network.c:31
static int ff_poll_interrupt(struct pollfd *p, nfds_t nfds, int timeout, AVIOInterruptCB *cb)
Definition: network.c:159
int av_usleep(unsigned usec)
Sleep for a period of time.
Definition: time.c:84
int64_t deadline_us
Definition: network.c:350
int ff_socket(int af, int type, int proto)
Definition: network.c:183
#define IN6_IS_ADDR_MULTICAST(a)
Definition: network.h:241
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
static double cb(void *priv, double x, double y)
Definition: vf_geq.c:112
int ff_listen_bind(int fd, const struct sockaddr *addr, socklen_t addrlen, int timeout, URLContext *h)
Bind to a file descriptor and poll for a connection.
Definition: network.c:246
int ff_network_init(void)
Definition: network.c:58
int ff_openssl_init(void)
Definition: tls_openssl.c:69
int ff_listen(int fd, const struct sockaddr *addr, socklen_t addrlen)
Bind to a file descriptor to an address without accepting connections.
Definition: network.c:210
void ff_gnutls_init(void)
Definition: tls_gnutls.c:56
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
int ff_listen_connect(int fd, const struct sockaddr *addr, socklen_t addrlen, int timeout, URLContext *h, int will_try_next)
Connect to a file descriptor and poll for result.
Definition: network.c:258
static void print_address_list(void *ctx, const struct addrinfo *addr, const char *title)
Definition: network.c:334
#define av_log(a,...)
Callback for checking whether to abort blocking functions.
Definition: avio.h:58
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
int ff_accept(int fd, int timeout, URLContext *h)
Poll for a single connection on the passed file descriptor.
Definition: network.c:228
const AVIOInterruptCB int_cb
Definition: ffmpeg.c:481
#define AVERROR(e)
Definition: error.h:43
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
simple assert() macros that are a bit more flexible than ISO C assert().
int ff_is_multicast_address(struct sockaddr *addr)
Definition: network.c:145
int ff_network_wait_fd_timeout(int fd, int write, int64_t timeout, AVIOInterruptCB *int_cb)
This works similarly to ff_network_wait_fd, but waits up to 'timeout' microseconds Uses ff_network_wa...
Definition: network.c:78
static int start_connect_attempt(struct ConnectionAttempt *attempt, struct addrinfo **ptr, int timeout_ms, URLContext *h, void(*customize_fd)(void *, int), void *customize_ctx)
Definition: network.c:356
int ai_addrlen
Definition: network.h:139
#define NI_NUMERICHOST
Definition: network.h:192
#define FFMIN(a, b)
Definition: common.h:96
#define ff_neterrno()
Definition: network.h:65
AVFormatContext * ctx
Definition: movenc.c:48
int ff_network_sleep_interruptible(int64_t timeout, AVIOInterruptCB *int_cb)
Waits for up to 'timeout' microseconds.
Definition: network.c:98
int ff_connect_parallel(struct addrinfo *addrs, int timeout_ms_per_address, int parallel, URLContext *h, int *fd, void(*customize_fd)(void *, int), void *customize_ctx)
Connect to any of the given addrinfo addresses, with multiple attempts running in parallel...
Definition: network.c:403
int ff_http_match_no_proxy(const char *no_proxy, const char *hostname)
Definition: network.c:551
int ff_socket_nonblock(int socket, int enable)
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:56
#define FF_ARRAY_ELEMS(a)
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:251
int ff_check_interrupt(AVIOInterruptCB *cb)
Check if the user has requested to interrupt a blocking function associated with cb.
Definition: avio.c:664
struct addrinfo * addr
Definition: network.c:351
void * buf
Definition: avisynth_c.h:690
Definition: url.h:38
GLint GLenum type
Definition: opengl_enc.c:105
int ai_protocol
Definition: network.h:138
#define IN_MULTICAST(a)
Definition: network.h:238
#define POLLING_TIME
Definition: network.h:246
void ff_gnutls_deinit(void)
Definition: tls_gnutls.c:67
int ai_socktype
Definition: network.h:137
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
Definition: time.c:56
uint8_t level
Definition: svq3.c:207
int av_strerror(int errnum, char *errbuf, size_t errbuf_size)
Put a description of the AVERROR code errnum in errbuf.
Definition: error.c:105
int
common internal api header.
struct addrinfo * ai_next
Definition: network.h:142
char * filename
specified URL
Definition: url.h:42
#define AVUNERROR(e)
Definition: error.h:44
#define getnameinfo
Definition: network.h:216
#define av_free(p)
void ff_tls_deinit(void)
Definition: network.c:46
int ff_network_wait_fd(int fd, int write)
Definition: network.c:69
void INT64 start
Definition: avisynth_c.h:690
void ff_openssl_deinit(void)
Definition: tls_openssl.c:99
unbuffered private I/O API
#define MAKEWORD(a, b)
Definition: windows2linux.h:56
struct sockaddr * ai_addr
Definition: network.h:140
static void interleave_addrinfo(struct addrinfo *base)
Definition: network.c:303
void ff_log_net_error(void *ctx, int level, const char *prefix)
Definition: network.c:581
int ai_family
Definition: network.h:136