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 "config.h"
22 #include "config_components.h"
23 #include "libavutil/attributes.h"
24 
25 #if CONFIG_TLS_PROTOCOL && CONFIG_OPENSSL
26 #include <openssl/opensslv.h>
27 #endif
28 
29 #include <fcntl.h>
30 #include "network.h"
31 #include "tls.h"
32 #include "url.h"
33 #include "libavutil/avassert.h"
34 #include "libavutil/mem.h"
35 #include "libavutil/time.h"
36 
37 int ff_tls_init(void)
38 {
39 #if CONFIG_TLS_PROTOCOL
40 #if CONFIG_GNUTLS
42 #endif
43 #endif
44  return 0;
45 }
46 
47 void ff_tls_deinit(void)
48 {
49 #if CONFIG_TLS_PROTOCOL
50 #if CONFIG_GNUTLS
52 #endif
53 #endif
54 }
55 
56 int ff_network_init(void)
57 {
58 #if HAVE_WINSOCK2_H
59  WSADATA wsaData;
60 
61  if (WSAStartup(MAKEWORD(1,1), &wsaData))
62  return 0;
63 #endif
64  return 1;
65 }
66 
67 int ff_network_wait_fd(int fd, int write)
68 {
69  int ev = write ? POLLOUT : POLLIN;
70  struct pollfd p = { .fd = fd, .events = ev, .revents = 0 };
71  int ret;
72  ret = poll(&p, 1, POLLING_TIME);
73  return ret < 0 ? ff_neterrno() : p.revents & (ev | POLLERR | POLLHUP) ? 0 : AVERROR(EAGAIN);
74 }
75 
76 int ff_network_wait_fd_timeout(int fd, int write, int64_t timeout, AVIOInterruptCB *int_cb)
77 {
78  int ret;
79  int64_t wait_start = 0;
80 
81  while (1) {
83  return AVERROR_EXIT;
84  ret = ff_network_wait_fd(fd, write);
85  if (ret != AVERROR(EAGAIN))
86  return ret;
87  if (timeout > 0) {
88  if (!wait_start)
89  wait_start = av_gettime_relative();
90  else if (av_gettime_relative() - wait_start > timeout)
91  return AVERROR(ETIMEDOUT);
92  }
93  }
94 }
95 
97 {
98  int64_t wait_start = av_gettime_relative();
99 
100  while (1) {
101  int64_t time_left;
102 
104  return AVERROR_EXIT;
105 
106  time_left = timeout - (av_gettime_relative() - wait_start);
107  if (time_left <= 0)
108  return AVERROR(ETIMEDOUT);
109 
110  av_usleep(FFMIN(time_left, POLLING_TIME * 1000));
111  }
112 }
113 
115 {
116 #if HAVE_WINSOCK2_H
117  WSACleanup();
118 #endif
119 }
120 
121 #if HAVE_WINSOCK2_H
122 int ff_neterrno(void)
123 {
124  int err = WSAGetLastError();
125  switch (err) {
126  case WSAEWOULDBLOCK:
127  return AVERROR(EAGAIN);
128  case WSAEINTR:
129  return AVERROR(EINTR);
130  case WSAEPROTONOSUPPORT:
131  return AVERROR(EPROTONOSUPPORT);
132  case WSAETIMEDOUT:
133  return AVERROR(ETIMEDOUT);
134  case WSAECONNREFUSED:
135  return AVERROR(ECONNREFUSED);
136  case WSAEINPROGRESS:
137  return AVERROR(EINPROGRESS);
138  }
139  return -err;
140 }
141 #endif
142 
143 int ff_is_multicast_address(struct sockaddr *addr)
144 {
145  if (addr->sa_family == AF_INET) {
146  return IN_MULTICAST(ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr));
147  }
148 #if HAVE_STRUCT_SOCKADDR_IN6
149  if (addr->sa_family == AF_INET6) {
150  return IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)addr)->sin6_addr);
151  }
152 #endif
153 
154  return 0;
155 }
156 
157 static int ff_poll_interrupt(struct pollfd *p, nfds_t nfds, int timeout,
159 {
160  int runs = timeout / POLLING_TIME;
161  int ret = 0;
162 
163  do {
164  if (ff_check_interrupt(cb))
165  return AVERROR_EXIT;
166  ret = poll(p, nfds, POLLING_TIME);
167  if (ret != 0) {
168  if (ret < 0)
169  ret = ff_neterrno();
170  if (ret == AVERROR(EINTR))
171  continue;
172  break;
173  }
174  } while (timeout <= 0 || runs-- > 0);
175 
176  if (!ret)
177  return AVERROR(ETIMEDOUT);
178  return ret;
179 }
180 
181 int ff_socket(int af, int type, int proto, void *logctx)
182 {
183  int fd;
184 
185 #ifdef SOCK_CLOEXEC
186  fd = socket(af, type | SOCK_CLOEXEC, proto);
187  if (fd == -1 && errno == EINVAL)
188 #endif
189  {
190  fd = socket(af, type, proto);
191 #if HAVE_FCNTL
192  if (fd != -1) {
193  if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
194  av_log(logctx, AV_LOG_DEBUG, "Failed to set close on exec\n");
195  }
196 #endif
197  }
198 #ifdef SO_NOSIGPIPE
199  if (fd != -1) {
200  if (setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &(int){1}, sizeof(int))) {
201  av_log(logctx, AV_LOG_WARNING, "setsockopt(SO_NOSIGPIPE) failed\n");
202  }
203  }
204 #endif
205  return fd;
206 }
207 
208 int ff_listen(int fd, const struct sockaddr *addr,
209  socklen_t addrlen, void *logctx)
210 {
211  int ret;
212  int reuse = 1;
213  if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))) {
214  av_log(logctx, AV_LOG_WARNING, "setsockopt(SO_REUSEADDR) failed\n");
215  }
216  ret = bind(fd, addr, addrlen);
217  if (ret)
218  return ff_neterrno();
219 
220  ret = listen(fd, 1);
221  if (ret)
222  return ff_neterrno();
223  return ret;
224 }
225 
226 int ff_accept(int fd, int timeout, URLContext *h)
227 {
228  int ret;
229  struct pollfd lp = { fd, POLLIN, 0 };
230 
231  ret = ff_poll_interrupt(&lp, 1, timeout, &h->interrupt_callback);
232  if (ret < 0)
233  return ret;
234 
235  ret = accept(fd, NULL, NULL);
236  if (ret < 0)
237  return ff_neterrno();
238  if (ff_socket_nonblock(ret, 1) < 0)
239  av_log(h, AV_LOG_DEBUG, "ff_socket_nonblock failed\n");
240 
241  return ret;
242 }
243 
244 int ff_listen_bind(int fd, const struct sockaddr *addr,
245  socklen_t addrlen, int timeout, URLContext *h)
246 {
247  int ret;
248  if ((ret = ff_listen(fd, addr, addrlen, h)) < 0)
249  return ret;
250  if ((ret = ff_accept(fd, timeout, h)) < 0)
251  return ret;
252  closesocket(fd);
253  return ret;
254 }
255 
256 int ff_listen_connect(int fd, const struct sockaddr *addr,
257  socklen_t addrlen, int timeout, URLContext *h,
258  int will_try_next)
259 {
260  struct pollfd p = {fd, POLLOUT, 0};
261  int ret;
262  socklen_t optlen;
263 
264  if (ff_socket_nonblock(fd, 1) < 0)
265  av_log(h, AV_LOG_DEBUG, "ff_socket_nonblock failed\n");
266 
267  while ((ret = connect(fd, addr, addrlen))) {
268  ret = ff_neterrno();
269  switch (ret) {
270  case AVERROR(EINTR):
271  if (ff_check_interrupt(&h->interrupt_callback))
272  return AVERROR_EXIT;
273  continue;
274  case AVERROR(EINPROGRESS):
275  case AVERROR(EAGAIN):
276  ret = ff_poll_interrupt(&p, 1, timeout, &h->interrupt_callback);
277  if (ret < 0)
278  return ret;
279  optlen = sizeof(ret);
280  if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen))
282  if (ret != 0) {
283  ret = AVERROR(ret);
284  if (will_try_next)
286  "Connection to %s failed (%s), trying next address\n",
287  h->filename, av_err2str(ret));
288  else
289  av_log(h, AV_LOG_ERROR, "Connection to %s failed: %s\n",
290  h->filename, av_err2str(ret));
291  }
293  default:
294  return ret;
295  }
296  }
297  return ret;
298 }
299 
300 static void interleave_addrinfo(struct addrinfo *base)
301 {
302  struct addrinfo **next = &base->ai_next;
303  while (*next) {
304  struct addrinfo *cur = *next;
305  // Iterate forward until we find an entry of a different family.
306  if (cur->ai_family == base->ai_family) {
307  next = &cur->ai_next;
308  continue;
309  }
310  if (cur == base->ai_next) {
311  // If the first one following base is of a different family, just
312  // move base forward one step and continue.
313  base = cur;
314  next = &base->ai_next;
315  continue;
316  }
317  // Unchain cur from the rest of the list from its current spot.
318  *next = cur->ai_next;
319  // Hook in cur directly after base.
320  cur->ai_next = base->ai_next;
321  base->ai_next = cur;
322  // Restart with a new base. We know that before moving the cur element,
323  // everything between the previous base and cur had the same family,
324  // different from cur->ai_family. Therefore, we can keep next pointing
325  // where it was, and continue from there with base at the one after
326  // cur.
327  base = cur->ai_next;
328  }
329 }
330 
331 static void print_address_list(void *ctx, const struct addrinfo *addr,
332  const char *title)
333 {
334  char hostbuf[100], portbuf[20];
335  av_log(ctx, AV_LOG_DEBUG, "%s:\n", title);
336  while (addr) {
337  getnameinfo(addr->ai_addr, addr->ai_addrlen,
338  hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf),
340  av_log(ctx, AV_LOG_DEBUG, "Address %s port %s\n", hostbuf, portbuf);
341  addr = addr->ai_next;
342  }
343 }
344 
346  int fd;
348  struct addrinfo *addr;
349 };
350 
351 // Returns < 0 on error, 0 on successfully started connection attempt,
352 // > 0 for a connection that succeeded already.
353 static int start_connect_attempt(struct ConnectionAttempt *attempt,
354  struct addrinfo **ptr, int timeout_ms,
355  URLContext *h,
356  int (*customize_fd)(void *, int, int), void *customize_ctx)
357 {
358  struct addrinfo *ai = *ptr;
359  int ret;
360 
361  *ptr = ai->ai_next;
362 
363  attempt->fd = ff_socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol, h);
364  if (attempt->fd < 0)
365  return ff_neterrno();
366  attempt->deadline_us = av_gettime_relative() + timeout_ms * 1000;
367  attempt->addr = ai;
368 
369  ff_socket_nonblock(attempt->fd, 1);
370 
371  if (customize_fd) {
372  ret = customize_fd(customize_ctx, attempt->fd, ai->ai_family);
373  if (ret) {
374  closesocket(attempt->fd);
375  attempt->fd = -1;
376  return ret;
377  }
378  }
379 
380  while ((ret = connect(attempt->fd, ai->ai_addr, ai->ai_addrlen))) {
381  ret = ff_neterrno();
382  switch (ret) {
383  case AVERROR(EINTR):
384  if (ff_check_interrupt(&h->interrupt_callback)) {
385  closesocket(attempt->fd);
386  attempt->fd = -1;
387  return AVERROR_EXIT;
388  }
389  continue;
390  case AVERROR(EINPROGRESS):
391  case AVERROR(EAGAIN):
392  return 0;
393  default:
394  closesocket(attempt->fd);
395  attempt->fd = -1;
396  return ret;
397  }
398  }
399  return 1;
400 }
401 
402 // Try a new connection to another address after 200 ms, as suggested in
403 // RFC 8305 (or sooner if an earlier attempt fails).
404 #define NEXT_ATTEMPT_DELAY_MS 200
405 
406 int ff_connect_parallel(struct addrinfo *addrs, int timeout_ms_per_address,
407  int parallel, URLContext *h, int *fd,
408  int (*customize_fd)(void *, int, int), void *customize_ctx)
409 {
410  struct ConnectionAttempt attempts[3];
411  struct pollfd pfd[3];
412  int nb_attempts = 0, i, j;
413  int64_t next_attempt_us = av_gettime_relative(), next_deadline_us;
414  int last_err = AVERROR(EIO);
415  socklen_t optlen;
416  char hostbuf[100], portbuf[20];
417 
418  if (parallel > FF_ARRAY_ELEMS(attempts))
419  parallel = FF_ARRAY_ELEMS(attempts);
420 
421  print_address_list(h, addrs, "Original list of addresses");
422  // This mutates the list, but the head of the list is still the same
423  // element, so the caller, who owns the list, doesn't need to get
424  // an updated pointer.
425  interleave_addrinfo(addrs);
426  print_address_list(h, addrs, "Interleaved list of addresses");
427 
428  while (nb_attempts > 0 || addrs) {
429  // Start a new connection attempt, if possible.
430  if (nb_attempts < parallel && addrs) {
431  getnameinfo(addrs->ai_addr, addrs->ai_addrlen,
432  hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf),
434  av_log(h, AV_LOG_VERBOSE, "Starting connection attempt to %s port %s\n",
435  hostbuf, portbuf);
436  last_err = start_connect_attempt(&attempts[nb_attempts], &addrs,
437  timeout_ms_per_address, h,
438  customize_fd, customize_ctx);
439  if (last_err < 0) {
440  av_log(h, AV_LOG_VERBOSE, "Connected attempt failed: %s\n",
441  av_err2str(last_err));
442  continue;
443  }
444  if (last_err > 0) {
445  for (i = 0; i < nb_attempts; i++)
446  closesocket(attempts[i].fd);
447  *fd = attempts[nb_attempts].fd;
448  return 0;
449  }
450  pfd[nb_attempts].fd = attempts[nb_attempts].fd;
451  pfd[nb_attempts].events = POLLOUT;
452  next_attempt_us = av_gettime_relative() + NEXT_ATTEMPT_DELAY_MS * 1000;
453  nb_attempts++;
454  }
455 
456  av_assert0(nb_attempts > 0);
457  // The connection attempts are sorted from oldest to newest, so the
458  // first one will have the earliest deadline.
459  next_deadline_us = attempts[0].deadline_us;
460  // If we can start another attempt in parallel, wait until that time.
461  if (nb_attempts < parallel && addrs)
462  next_deadline_us = FFMIN(next_deadline_us, next_attempt_us);
463  last_err = ff_poll_interrupt(pfd, nb_attempts,
464  (next_deadline_us - av_gettime_relative())/1000,
465  &h->interrupt_callback);
466  if (last_err < 0 && last_err != AVERROR(ETIMEDOUT))
467  break;
468 
469  // Check the status from the poll output.
470  for (i = 0; i < nb_attempts; i++) {
471  last_err = 0;
472  if (pfd[i].revents) {
473  // Some sort of action for this socket, check its status (either
474  // a successful connection or an error).
475  optlen = sizeof(last_err);
476  if (getsockopt(attempts[i].fd, SOL_SOCKET, SO_ERROR, &last_err, &optlen))
477  last_err = ff_neterrno();
478  else if (last_err != 0)
479  last_err = AVERROR(last_err);
480  if (last_err == 0) {
481  // Everything is ok, we seem to have a successful
482  // connection. Close other sockets and return this one.
483  for (j = 0; j < nb_attempts; j++)
484  if (j != i)
485  closesocket(attempts[j].fd);
486  *fd = attempts[i].fd;
487  getnameinfo(attempts[i].addr->ai_addr, attempts[i].addr->ai_addrlen,
488  hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf),
490  av_log(h, AV_LOG_VERBOSE, "Successfully connected to %s port %s\n",
491  hostbuf, portbuf);
492  return 0;
493  }
494  }
495  if (attempts[i].deadline_us < av_gettime_relative() && !last_err)
496  last_err = AVERROR(ETIMEDOUT);
497  if (!last_err)
498  continue;
499  // Error (or timeout) for this socket; close the socket and remove
500  // it from the attempts/pfd arrays, to let a new attempt start
501  // directly.
502  getnameinfo(attempts[i].addr->ai_addr, attempts[i].addr->ai_addrlen,
503  hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf),
505  av_log(h, AV_LOG_VERBOSE, "Connection attempt to %s port %s "
506  "failed: %s\n", hostbuf, portbuf, av_err2str(last_err));
507  closesocket(attempts[i].fd);
508  memmove(&attempts[i], &attempts[i + 1],
509  (nb_attempts - i - 1) * sizeof(*attempts));
510  memmove(&pfd[i], &pfd[i + 1],
511  (nb_attempts - i - 1) * sizeof(*pfd));
512  i--;
513  nb_attempts--;
514  }
515  }
516  for (i = 0; i < nb_attempts; i++)
517  closesocket(attempts[i].fd);
518  if (last_err >= 0)
519  last_err = AVERROR(ECONNREFUSED);
520  if (last_err != AVERROR_EXIT) {
521  av_log(h, AV_LOG_ERROR, "Connection to %s failed: %s\n",
522  h->filename, av_err2str(last_err));
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  av_log(ctx, level, "%s: %s\n", prefix, av_err2str(ff_neterrno()));
584 }
ConnectionAttempt::fd
int fd
Definition: network.c:346
ConnectionAttempt::addr
struct addrinfo * addr
Definition: network.c:348
av_gettime_relative
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
Definition: time.c:56
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:300
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:157
ff_gnutls_init
void ff_gnutls_init(void)
Definition: tls_gnutls.c:345
ff_log_net_error
void ff_log_net_error(void *ctx, int level, const char *prefix)
Definition: network.c:581
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:331
ff_network_close
void ff_network_close(void)
Definition: network.c:114
ConnectionAttempt::deadline_us
int64_t deadline_us
Definition: network.c:347
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:56
ff_tls_init
int ff_tls_init(void)
Definition: network.c:37
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:356
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:855
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:244
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
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:84
av_fallthrough
#define av_fallthrough
Definition: attributes.h:67
ff_http_match_no_proxy
int ff_http_match_no_proxy(const char *no_proxy, const char *hostname)
Definition: network.c:551
NULL
#define NULL
Definition: coverity.c:32
ff_is_multicast_address
int ff_is_multicast_address(struct sockaddr *addr)
Definition: network.c:143
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:256
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:76
time.h
ff_neterrno
#define ff_neterrno()
Definition: network.h:68
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:226
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)
attributes.h
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:96
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:312
ConnectionAttempt
Definition: network.c:345
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:406
ff_tls_deinit
void ff_tls_deinit(void)
Definition: network.c:47
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:208
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:181
addrinfo
Definition: network.h:137
NEXT_ATTEMPT_DELAY_MS
#define NEXT_ATTEMPT_DELAY_MS
Definition: network.c:404
match_host_pattern
static int match_host_pattern(const char *pattern, const char *hostname)
Definition: network.c:527
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:353
ff_network_wait_fd
int ff_network_wait_fd(int fd, int write)
Definition: network.c:67