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 <string.h>
22 
23 #include "config.h"
24 #include "config_components.h"
25 #include "libavutil/attributes.h"
26 
27 #if CONFIG_TLS_PROTOCOL && CONFIG_OPENSSL
28 #include <openssl/opensslv.h>
29 #endif
30 
31 #include <fcntl.h>
32 #include "network.h"
33 #include "tls.h"
34 #include "url.h"
35 #include "libavutil/avassert.h"
36 #include "libavutil/mem.h"
37 #include "libavutil/time.h"
38 
39 int ff_tls_init(void)
40 {
41 #if CONFIG_TLS_PROTOCOL
42 #if CONFIG_GNUTLS
44 #endif
45 #endif
46  return 0;
47 }
48 
49 void ff_tls_deinit(void)
50 {
51 #if CONFIG_TLS_PROTOCOL
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) {
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 
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, void *logctx)
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(logctx, 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(logctx, 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, void *logctx)
212 {
213  int ret;
214  int reuse = 1;
215  if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))) {
216  av_log(logctx, 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(h, 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, h)) < 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(h, 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):
273  if (ff_check_interrupt(&h->interrupt_callback))
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))
284  if (ret != 0) {
285  ret = AVERROR(ret);
286  if (will_try_next)
288  "Connection to %s failed (%s), trying next address\n",
289  h->filename, av_err2str(ret));
290  else
291  av_log(h, AV_LOG_ERROR, "Connection to %s failed: %s\n",
292  h->filename, av_err2str(ret));
293  }
295  default:
296  return ret;
297  }
298  }
299  return ret;
300 }
301 
302 static void interleave_addrinfo(struct addrinfo *base)
303 {
304  struct addrinfo **next = &base->ai_next;
305  while (*next) {
306  struct addrinfo *cur = *next;
307  // Iterate forward until we find an entry of a different family.
308  if (cur->ai_family == base->ai_family) {
309  next = &cur->ai_next;
310  continue;
311  }
312  if (cur == base->ai_next) {
313  // If the first one following base is of a different family, just
314  // move base forward one step and continue.
315  base = cur;
316  next = &base->ai_next;
317  continue;
318  }
319  // Unchain cur from the rest of the list from its current spot.
320  *next = cur->ai_next;
321  // Hook in cur directly after base.
322  cur->ai_next = base->ai_next;
323  base->ai_next = cur;
324  // Restart with a new base. We know that before moving the cur element,
325  // everything between the previous base and cur had the same family,
326  // different from cur->ai_family. Therefore, we can keep next pointing
327  // where it was, and continue from there with base at the one after
328  // cur.
329  base = cur->ai_next;
330  }
331 }
332 
333 static void print_address_list(void *ctx, const struct addrinfo *addr,
334  const char *title)
335 {
336  char hostbuf[100], portbuf[20];
337  av_log(ctx, AV_LOG_DEBUG, "%s:\n", title);
338  while (addr) {
339  getnameinfo(addr->ai_addr, addr->ai_addrlen,
340  hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf),
342  av_log(ctx, AV_LOG_DEBUG, "Address %s port %s\n", hostbuf, portbuf);
343  addr = addr->ai_next;
344  }
345 }
346 
348  int fd;
350  struct addrinfo *addr;
351 };
352 
353 // Returns < 0 on error, 0 on successfully started connection attempt,
354 // > 0 for a connection that succeeded already.
355 static int start_connect_attempt(struct ConnectionAttempt *attempt,
356  struct addrinfo **ptr, int timeout_ms,
357  URLContext *h,
358  int (*customize_fd)(void *, int, int), void *customize_ctx)
359 {
360  struct addrinfo *ai = *ptr;
361  int ret;
362 
363  *ptr = ai->ai_next;
364 
365  attempt->fd = ff_socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol, h);
366  if (attempt->fd < 0)
367  return ff_neterrno();
368  attempt->deadline_us = av_gettime_relative() + timeout_ms * 1000;
369  attempt->addr = ai;
370 
371  ff_socket_nonblock(attempt->fd, 1);
372 
373  if (customize_fd) {
374  ret = customize_fd(customize_ctx, attempt->fd, ai->ai_family);
375  if (ret) {
376  closesocket(attempt->fd);
377  attempt->fd = -1;
378  return ret;
379  }
380  }
381 
382  while ((ret = connect(attempt->fd, ai->ai_addr, ai->ai_addrlen))) {
383  ret = ff_neterrno();
384  switch (ret) {
385  case AVERROR(EINTR):
386  if (ff_check_interrupt(&h->interrupt_callback)) {
387  closesocket(attempt->fd);
388  attempt->fd = -1;
389  return AVERROR_EXIT;
390  }
391  continue;
392  case AVERROR(EINPROGRESS):
393  case AVERROR(EAGAIN):
394  return 0;
395  default:
396  closesocket(attempt->fd);
397  attempt->fd = -1;
398  return ret;
399  }
400  }
401  return 1;
402 }
403 
404 // Try a new connection to another address after 200 ms, as suggested in
405 // RFC 8305 (or sooner if an earlier attempt fails).
406 #define NEXT_ATTEMPT_DELAY_MS 200
407 
408 int ff_connect_parallel(struct addrinfo *addrs, int timeout_ms_per_address,
409  int parallel, URLContext *h, int *fd,
410  int (*customize_fd)(void *, int, int), void *customize_ctx)
411 {
412  struct ConnectionAttempt attempts[3];
413  struct pollfd pfd[3];
414  int nb_attempts = 0, i, j;
415  int64_t next_attempt_us = av_gettime_relative(), next_deadline_us;
416  int last_err = AVERROR(EIO);
417  socklen_t optlen;
418  char hostbuf[100], portbuf[20];
419 
420  if (parallel > FF_ARRAY_ELEMS(attempts))
421  parallel = FF_ARRAY_ELEMS(attempts);
422 
423  print_address_list(h, addrs, "Original list of addresses");
424  // This mutates the list, but the head of the list is still the same
425  // element, so the caller, who owns the list, doesn't need to get
426  // an updated pointer.
427  interleave_addrinfo(addrs);
428  print_address_list(h, addrs, "Interleaved list of addresses");
429 
430  while (nb_attempts > 0 || addrs) {
431  // Start a new connection attempt, if possible.
432  if (nb_attempts < parallel && addrs) {
433  getnameinfo(addrs->ai_addr, addrs->ai_addrlen,
434  hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf),
436  av_log(h, AV_LOG_VERBOSE, "Starting connection attempt to %s port %s\n",
437  hostbuf, portbuf);
438  last_err = start_connect_attempt(&attempts[nb_attempts], &addrs,
439  timeout_ms_per_address, h,
440  customize_fd, customize_ctx);
441  if (last_err < 0) {
442  av_log(h, AV_LOG_VERBOSE, "Connected attempt failed: %s\n",
443  av_err2str(last_err));
444  continue;
445  }
446  if (last_err > 0) {
447  for (i = 0; i < nb_attempts; i++)
448  closesocket(attempts[i].fd);
449  *fd = attempts[nb_attempts].fd;
450  return 0;
451  }
452  pfd[nb_attempts].fd = attempts[nb_attempts].fd;
453  pfd[nb_attempts].events = POLLOUT;
454  next_attempt_us = av_gettime_relative() + NEXT_ATTEMPT_DELAY_MS * 1000;
455  nb_attempts++;
456  }
457 
458  av_assert0(nb_attempts > 0);
459  // The connection attempts are sorted from oldest to newest, so the
460  // first one will have the earliest deadline.
461  next_deadline_us = attempts[0].deadline_us;
462  // If we can start another attempt in parallel, wait until that time.
463  if (nb_attempts < parallel && addrs)
464  next_deadline_us = FFMIN(next_deadline_us, next_attempt_us);
465  last_err = ff_poll_interrupt(pfd, nb_attempts,
466  (next_deadline_us - av_gettime_relative())/1000,
467  &h->interrupt_callback);
468  if (last_err < 0 && last_err != AVERROR(ETIMEDOUT))
469  break;
470 
471  // Check the status from the poll output.
472  for (i = 0; i < nb_attempts; i++) {
473  last_err = 0;
474  if (pfd[i].revents) {
475  // Some sort of action for this socket, check its status (either
476  // a successful connection or an error).
477  optlen = sizeof(last_err);
478  if (getsockopt(attempts[i].fd, SOL_SOCKET, SO_ERROR, &last_err, &optlen))
479  last_err = ff_neterrno();
480  else if (last_err != 0)
481  last_err = AVERROR(last_err);
482  if (last_err == 0) {
483  // Everything is ok, we seem to have a successful
484  // connection. Close other sockets and return this one.
485  for (j = 0; j < nb_attempts; j++)
486  if (j != i)
487  closesocket(attempts[j].fd);
488  *fd = attempts[i].fd;
489  getnameinfo(attempts[i].addr->ai_addr, attempts[i].addr->ai_addrlen,
490  hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf),
492  av_log(h, AV_LOG_VERBOSE, "Successfully connected to %s port %s\n",
493  hostbuf, portbuf);
494  return 0;
495  }
496  }
497  if (attempts[i].deadline_us < av_gettime_relative() && !last_err)
498  last_err = AVERROR(ETIMEDOUT);
499  if (!last_err)
500  continue;
501  // Error (or timeout) for this socket; close the socket and remove
502  // it from the attempts/pfd arrays, to let a new attempt start
503  // directly.
504  getnameinfo(attempts[i].addr->ai_addr, attempts[i].addr->ai_addrlen,
505  hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf),
507  av_log(h, AV_LOG_VERBOSE, "Connection attempt to %s port %s "
508  "failed: %s\n", hostbuf, portbuf, av_err2str(last_err));
509  closesocket(attempts[i].fd);
510  memmove(&attempts[i], &attempts[i + 1],
511  (nb_attempts - i - 1) * sizeof(*attempts));
512  memmove(&pfd[i], &pfd[i + 1],
513  (nb_attempts - i - 1) * sizeof(*pfd));
514  i--;
515  nb_attempts--;
516  }
517  }
518  for (i = 0; i < nb_attempts; i++)
519  closesocket(attempts[i].fd);
520  if (last_err >= 0)
521  last_err = AVERROR(ECONNREFUSED);
522  if (last_err != AVERROR_EXIT) {
523  av_log(h, AV_LOG_ERROR, "Connection to %s failed: %s\n",
524  h->filename, av_err2str(last_err));
525  }
526  return last_err;
527 }
528 
529 static int match_host_pattern(const char *pattern, const char *hostname)
530 {
531  int len_p, len_h;
532  if (!strcmp(pattern, "*"))
533  return 1;
534  // Skip a possible *. at the start of the pattern
535  if (pattern[0] == '*')
536  pattern++;
537  if (pattern[0] == '.')
538  pattern++;
539  len_p = strlen(pattern);
540  len_h = strlen(hostname);
541  if (len_p > len_h)
542  return 0;
543  // Simply check if the end of hostname is equal to 'pattern'
544  if (!strcmp(pattern, &hostname[len_h - len_p])) {
545  if (len_h == len_p)
546  return 1; // Exact match
547  if (hostname[len_h - len_p - 1] == '.')
548  return 1; // The matched substring is a domain and not just a substring of a domain
549  }
550  return 0;
551 }
552 
553 int ff_http_match_no_proxy(const char *no_proxy, const char *hostname)
554 {
555  char *buf, *start;
556  int ret = 0;
557  if (!no_proxy)
558  return 0;
559  if (!hostname)
560  return 0;
561  buf = av_strdup(no_proxy);
562  if (!buf)
563  return 0;
564  start = buf;
565  while (start) {
566  char *sep, *next = NULL;
567  start += strspn(start, " ,");
568  sep = start + strcspn(start, " ,");
569  if (*sep) {
570  next = sep + 1;
571  *sep = '\0';
572  }
573  if (match_host_pattern(start, hostname)) {
574  ret = 1;
575  break;
576  }
577  start = next;
578  }
579  av_free(buf);
580  return ret;
581 }
582 
583 void ff_log_net_error(void *ctx, int level, const char* prefix)
584 {
585  av_log(ctx, level, "%s: %s\n", prefix, av_err2str(ff_neterrno()));
586 }
ConnectionAttempt::fd
int fd
Definition: network.c:348
ConnectionAttempt::addr
struct addrinfo * addr
Definition: network.c:350
av_gettime_relative
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
Definition: time.c:57
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
level
uint8_t level
Definition: svq3.c:208
interleave_addrinfo
static void interleave_addrinfo(struct addrinfo *base)
Definition: network.c:302
AVERROR
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
cb
static double cb(void *priv, double x, double y)
Definition: vf_geq.c:247
int64_t
long long int64_t
Definition: coverity.c:34
NI_NUMERICSERV
#define NI_NUMERICSERV
Definition: network.h:203
ff_poll_interrupt
static int ff_poll_interrupt(struct pollfd *p, nfds_t nfds, int timeout, AVIOInterruptCB *cb)
Definition: network.c:159
ff_gnutls_init
void ff_gnutls_init(void)
Definition: tls_gnutls.c:348
ff_log_net_error
void ff_log_net_error(void *ctx, int level, const char *prefix)
Definition: network.c:583
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
base
uint8_t base
Definition: vp3data.h:128
print_address_list
static void print_address_list(void *ctx, const struct addrinfo *addr, const char *title)
Definition: network.c:333
ff_network_close
void ff_network_close(void)
Definition: network.c:116
ConnectionAttempt::deadline_us
int64_t deadline_us
Definition: network.c:349
IN6_IS_ADDR_MULTICAST
#define IN6_IS_ADDR_MULTICAST(a)
Definition: network.h:244
ff_network_init
int ff_network_init(void)
Definition: network.c:58
ff_tls_init
int ff_tls_init(void)
Definition: network.c:39
AVIOInterruptCB
Callback for checking whether to abort blocking functions.
Definition: avio.h:59
AVUNERROR
#define AVUNERROR(e)
Definition: error.h:46
ff_gnutls_deinit
void ff_gnutls_deinit(void)
Definition: tls_gnutls.c:359
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
ff_check_interrupt
int ff_check_interrupt(AVIOInterruptCB *cb)
Check if the user has requested to interrupt a blocking function associated with cb.
Definition: avio.c:860
ff_listen_bind
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
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
customize_fd
static int customize_fd(void *ctx, int fd, int family)
Definition: tcp.c:80
prefix
char prefix[8]
Definition: uops_macros_gen.c:49
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
av_usleep
int av_usleep(unsigned usec)
Sleep for a period of time.
Definition: time.c:93
ff_http_match_no_proxy
int ff_http_match_no_proxy(const char *no_proxy, const char *hostname)
Definition: network.c:553
NULL
#define NULL
Definition: coverity.c:32
av_fallthrough
#define av_fallthrough
Definition: attributes.h:67
ff_is_multicast_address
int ff_is_multicast_address(struct sockaddr *addr)
Definition: network.c:145
ff_listen_connect
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
ff_network_wait_fd_timeout
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
time.h
ff_neterrno
#define ff_neterrno()
Definition: network.h:68
attributes.h
addrinfo::ai_addr
struct sockaddr * ai_addr
Definition: network.h:143
addrinfo::ai_family
int ai_family
Definition: network.h:139
NI_NUMERICHOST
#define NI_NUMERICHOST
Definition: network.h:195
ff_accept
int ff_accept(int fd, int timeout, URLContext *h)
Poll for a single connection on the passed file descriptor.
Definition: network.c:228
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:122
addrinfo::ai_protocol
int ai_protocol
Definition: network.h:141
ff_socket_nonblock
int ff_socket_nonblock(int socket, int enable)
addrinfo::ai_next
struct addrinfo * ai_next
Definition: network.h:145
addrinfo::ai_addrlen
int ai_addrlen
Definition: network.h:142
URLContext
Definition: url.h:35
ff_network_sleep_interruptible
int ff_network_sleep_interruptible(int64_t timeout, AVIOInterruptCB *int_cb)
Waits for up to 'timeout' microseconds.
Definition: network.c:98
getnameinfo
#define getnameinfo
Definition: network.h:219
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
url.h
int_cb
const AVIOInterruptCB int_cb
Definition: ffmpeg.c:322
ConnectionAttempt
Definition: network.c:347
ff_connect_parallel
int ff_connect_parallel(struct addrinfo *addrs, int timeout_ms_per_address, int parallel, URLContext *h, int *fd, int(*customize_fd)(void *, int, int), void *customize_ctx)
Connect to any of the given addrinfo addresses, with multiple attempts running in parallel.
Definition: network.c:408
ff_tls_deinit
void ff_tls_deinit(void)
Definition: network.c:49
ret
ret
Definition: filter_design.txt:187
addrinfo::ai_socktype
int ai_socktype
Definition: network.h:140
network.h
ff_listen
int ff_listen(int fd, const struct sockaddr *addr, socklen_t addrlen, void *logctx)
Bind to a file descriptor to an address without accepting connections.
Definition: network.c:210
tls.h
IN_MULTICAST
#define IN_MULTICAST(a)
Definition: network.h:241
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
mem.h
av_strdup
#define av_strdup(s)
Definition: ops_asmgen.c:47
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
POLLING_TIME
#define POLLING_TIME
Definition: network.h:249
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
h
h
Definition: vp9dsp_template.c:2070
AVERROR_EXIT
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:58
ff_socket
int ff_socket(int af, int type, int proto, void *logctx)
Definition: network.c:183
addrinfo
Definition: network.h:137
NEXT_ATTEMPT_DELAY_MS
#define NEXT_ATTEMPT_DELAY_MS
Definition: network.c:406
match_host_pattern
static int match_host_pattern(const char *pattern, const char *hostname)
Definition: network.c:529
start_connect_attempt
static int start_connect_attempt(struct ConnectionAttempt *attempt, struct addrinfo **ptr, int timeout_ms, URLContext *h, int(*customize_fd)(void *, int, int), void *customize_ctx)
Definition: network.c:355
ff_network_wait_fd
int ff_network_wait_fd(int fd, int write)
Definition: network.c:69