FFmpeg
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&#39;s core.
void ff_network_close(void)
Definition: network.c:116
GLint GLenum type
Definition: opengl_enc.c:104
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
uint8_t base
Definition: vp3data.h:202
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 i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#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 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 &#39;timeout&#39; 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 &#39;timeout&#39; 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:766
Definition: url.h:38
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:766
void ff_openssl_deinit(void)
Definition: tls_openssl.c:99
unbuffered private I/O API
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
#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