FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules 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 "config.h"
22 #include "config_components.h"
23 
24 #if CONFIG_TLS_PROTOCOL && CONFIG_OPENSSL
25 #include <openssl/opensslv.h>
26 #endif
27 
28 #include <fcntl.h>
29 #include "network.h"
30 #include "tls.h"
31 #include "url.h"
32 #include "libavutil/avassert.h"
33 #include "libavutil/mem.h"
34 #include "libavutil/time.h"
35 
36 int ff_tls_init(void)
37 {
38 #if CONFIG_TLS_PROTOCOL
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_GNUTLS
51 #endif
52 #endif
53 }
54 
55 int ff_network_init(void)
56 {
57 #if HAVE_WINSOCK2_H
58  WSADATA wsaData;
59 
60  if (WSAStartup(MAKEWORD(1,1), &wsaData))
61  return 0;
62 #endif
63  return 1;
64 }
65 
66 int ff_network_wait_fd(int fd, int write)
67 {
68  int ev = write ? POLLOUT : POLLIN;
69  struct pollfd p = { .fd = fd, .events = ev, .revents = 0 };
70  int ret;
71  ret = poll(&p, 1, POLLING_TIME);
72  return ret < 0 ? ff_neterrno() : p.revents & (ev | POLLERR | POLLHUP) ? 0 : AVERROR(EAGAIN);
73 }
74 
75 int ff_network_wait_fd_timeout(int fd, int write, int64_t timeout, AVIOInterruptCB *int_cb)
76 {
77  int ret;
78  int64_t wait_start = 0;
79 
80  while (1) {
82  return AVERROR_EXIT;
83  ret = ff_network_wait_fd(fd, write);
84  if (ret != AVERROR(EAGAIN))
85  return ret;
86  if (timeout > 0) {
87  if (!wait_start)
88  wait_start = av_gettime_relative();
89  else if (av_gettime_relative() - wait_start > timeout)
90  return AVERROR(ETIMEDOUT);
91  }
92  }
93 }
94 
96 {
97  int64_t wait_start = av_gettime_relative();
98 
99  while (1) {
100  int64_t time_left;
101 
103  return AVERROR_EXIT;
104 
105  time_left = timeout - (av_gettime_relative() - wait_start);
106  if (time_left <= 0)
107  return AVERROR(ETIMEDOUT);
108 
109  av_usleep(FFMIN(time_left, POLLING_TIME * 1000));
110  }
111 }
112 
114 {
115 #if HAVE_WINSOCK2_H
116  WSACleanup();
117 #endif
118 }
119 
120 #if HAVE_WINSOCK2_H
121 int ff_neterrno(void)
122 {
123  int err = WSAGetLastError();
124  switch (err) {
125  case WSAEWOULDBLOCK:
126  return AVERROR(EAGAIN);
127  case WSAEINTR:
128  return AVERROR(EINTR);
129  case WSAEPROTONOSUPPORT:
130  return AVERROR(EPROTONOSUPPORT);
131  case WSAETIMEDOUT:
132  return AVERROR(ETIMEDOUT);
133  case WSAECONNREFUSED:
134  return AVERROR(ECONNREFUSED);
135  case WSAEINPROGRESS:
136  return AVERROR(EINPROGRESS);
137  }
138  return -err;
139 }
140 #endif
141 
142 int ff_is_multicast_address(struct sockaddr *addr)
143 {
144  if (addr->sa_family == AF_INET) {
145  return IN_MULTICAST(ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr));
146  }
147 #if HAVE_STRUCT_SOCKADDR_IN6
148  if (addr->sa_family == AF_INET6) {
149  return IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)addr)->sin6_addr);
150  }
151 #endif
152 
153  return 0;
154 }
155 
156 static int ff_poll_interrupt(struct pollfd *p, nfds_t nfds, int timeout,
158 {
159  int runs = timeout / POLLING_TIME;
160  int ret = 0;
161 
162  do {
163  if (ff_check_interrupt(cb))
164  return AVERROR_EXIT;
165  ret = poll(p, nfds, POLLING_TIME);
166  if (ret != 0) {
167  if (ret < 0)
168  ret = ff_neterrno();
169  if (ret == AVERROR(EINTR))
170  continue;
171  break;
172  }
173  } while (timeout <= 0 || runs-- > 0);
174 
175  if (!ret)
176  return AVERROR(ETIMEDOUT);
177  return ret;
178 }
179 
180 int ff_socket(int af, int type, int proto, void *logctx)
181 {
182  int fd;
183 
184 #ifdef SOCK_CLOEXEC
185  fd = socket(af, type | SOCK_CLOEXEC, proto);
186  if (fd == -1 && errno == EINVAL)
187 #endif
188  {
189  fd = socket(af, type, proto);
190 #if HAVE_FCNTL
191  if (fd != -1) {
192  if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
193  av_log(logctx, AV_LOG_DEBUG, "Failed to set close on exec\n");
194  }
195 #endif
196  }
197 #ifdef SO_NOSIGPIPE
198  if (fd != -1) {
199  if (setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &(int){1}, sizeof(int))) {
200  av_log(logctx, AV_LOG_WARNING, "setsockopt(SO_NOSIGPIPE) failed\n");
201  }
202  }
203 #endif
204  return fd;
205 }
206 
207 int ff_listen(int fd, const struct sockaddr *addr,
208  socklen_t addrlen, void *logctx)
209 {
210  int ret;
211  int reuse = 1;
212  if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))) {
213  av_log(logctx, AV_LOG_WARNING, "setsockopt(SO_REUSEADDR) failed\n");
214  }
215  ret = bind(fd, addr, addrlen);
216  if (ret)
217  return ff_neterrno();
218 
219  ret = listen(fd, 1);
220  if (ret)
221  return ff_neterrno();
222  return ret;
223 }
224 
225 int ff_accept(int fd, int timeout, URLContext *h)
226 {
227  int ret;
228  struct pollfd lp = { fd, POLLIN, 0 };
229 
230  ret = ff_poll_interrupt(&lp, 1, timeout, &h->interrupt_callback);
231  if (ret < 0)
232  return ret;
233 
234  ret = accept(fd, NULL, NULL);
235  if (ret < 0)
236  return ff_neterrno();
237  if (ff_socket_nonblock(ret, 1) < 0)
238  av_log(h, AV_LOG_DEBUG, "ff_socket_nonblock failed\n");
239 
240  return ret;
241 }
242 
243 int ff_listen_bind(int fd, const struct sockaddr *addr,
244  socklen_t addrlen, int timeout, URLContext *h)
245 {
246  int ret;
247  if ((ret = ff_listen(fd, addr, addrlen, h)) < 0)
248  return ret;
249  if ((ret = ff_accept(fd, timeout, h)) < 0)
250  return ret;
251  closesocket(fd);
252  return ret;
253 }
254 
255 int ff_listen_connect(int fd, const struct sockaddr *addr,
256  socklen_t addrlen, int timeout, URLContext *h,
257  int will_try_next)
258 {
259  struct pollfd p = {fd, POLLOUT, 0};
260  int ret;
261  socklen_t optlen;
262 
263  if (ff_socket_nonblock(fd, 1) < 0)
264  av_log(h, AV_LOG_DEBUG, "ff_socket_nonblock failed\n");
265 
266  while ((ret = connect(fd, addr, addrlen))) {
267  ret = ff_neterrno();
268  switch (ret) {
269  case AVERROR(EINTR):
270  if (ff_check_interrupt(&h->interrupt_callback))
271  return AVERROR_EXIT;
272  continue;
273  case AVERROR(EINPROGRESS):
274  case AVERROR(EAGAIN):
275  ret = ff_poll_interrupt(&p, 1, timeout, &h->interrupt_callback);
276  if (ret < 0)
277  return ret;
278  optlen = sizeof(ret);
279  if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen))
281  if (ret != 0) {
282  ret = AVERROR(ret);
283  if (will_try_next)
285  "Connection to %s failed (%s), trying next address\n",
286  h->filename, av_err2str(ret));
287  else
288  av_log(h, AV_LOG_ERROR, "Connection to %s failed: %s\n",
289  h->filename, av_err2str(ret));
290  }
291  default:
292  return ret;
293  }
294  }
295  return ret;
296 }
297 
298 static void interleave_addrinfo(struct addrinfo *base)
299 {
300  struct addrinfo **next = &base->ai_next;
301  while (*next) {
302  struct addrinfo *cur = *next;
303  // Iterate forward until we find an entry of a different family.
304  if (cur->ai_family == base->ai_family) {
305  next = &cur->ai_next;
306  continue;
307  }
308  if (cur == base->ai_next) {
309  // If the first one following base is of a different family, just
310  // move base forward one step and continue.
311  base = cur;
312  next = &base->ai_next;
313  continue;
314  }
315  // Unchain cur from the rest of the list from its current spot.
316  *next = cur->ai_next;
317  // Hook in cur directly after base.
318  cur->ai_next = base->ai_next;
319  base->ai_next = cur;
320  // Restart with a new base. We know that before moving the cur element,
321  // everything between the previous base and cur had the same family,
322  // different from cur->ai_family. Therefore, we can keep next pointing
323  // where it was, and continue from there with base at the one after
324  // cur.
325  base = cur->ai_next;
326  }
327 }
328 
329 static void print_address_list(void *ctx, const struct addrinfo *addr,
330  const char *title)
331 {
332  char hostbuf[100], portbuf[20];
333  av_log(ctx, AV_LOG_DEBUG, "%s:\n", title);
334  while (addr) {
335  getnameinfo(addr->ai_addr, addr->ai_addrlen,
336  hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf),
338  av_log(ctx, AV_LOG_DEBUG, "Address %s port %s\n", hostbuf, portbuf);
339  addr = addr->ai_next;
340  }
341 }
342 
344  int fd;
346  struct addrinfo *addr;
347 };
348 
349 // Returns < 0 on error, 0 on successfully started connection attempt,
350 // > 0 for a connection that succeeded already.
351 static int start_connect_attempt(struct ConnectionAttempt *attempt,
352  struct addrinfo **ptr, int timeout_ms,
353  URLContext *h,
354  int (*customize_fd)(void *, int, int), void *customize_ctx)
355 {
356  struct addrinfo *ai = *ptr;
357  int ret;
358 
359  *ptr = ai->ai_next;
360 
361  attempt->fd = ff_socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol, h);
362  if (attempt->fd < 0)
363  return ff_neterrno();
364  attempt->deadline_us = av_gettime_relative() + timeout_ms * 1000;
365  attempt->addr = ai;
366 
367  ff_socket_nonblock(attempt->fd, 1);
368 
369  if (customize_fd) {
370  ret = customize_fd(customize_ctx, attempt->fd, ai->ai_family);
371  if (ret) {
372  closesocket(attempt->fd);
373  attempt->fd = -1;
374  return ret;
375  }
376  }
377 
378  while ((ret = connect(attempt->fd, ai->ai_addr, ai->ai_addrlen))) {
379  ret = ff_neterrno();
380  switch (ret) {
381  case AVERROR(EINTR):
382  if (ff_check_interrupt(&h->interrupt_callback)) {
383  closesocket(attempt->fd);
384  attempt->fd = -1;
385  return AVERROR_EXIT;
386  }
387  continue;
388  case AVERROR(EINPROGRESS):
389  case AVERROR(EAGAIN):
390  return 0;
391  default:
392  closesocket(attempt->fd);
393  attempt->fd = -1;
394  return ret;
395  }
396  }
397  return 1;
398 }
399 
400 // Try a new connection to another address after 200 ms, as suggested in
401 // RFC 8305 (or sooner if an earlier attempt fails).
402 #define NEXT_ATTEMPT_DELAY_MS 200
403 
404 int ff_connect_parallel(struct addrinfo *addrs, int timeout_ms_per_address,
405  int parallel, URLContext *h, int *fd,
406  int (*customize_fd)(void *, int, int), void *customize_ctx)
407 {
408  struct ConnectionAttempt attempts[3];
409  struct pollfd pfd[3];
410  int nb_attempts = 0, i, j;
411  int64_t next_attempt_us = av_gettime_relative(), next_deadline_us;
412  int last_err = AVERROR(EIO);
413  socklen_t optlen;
414  char hostbuf[100], portbuf[20];
415 
416  if (parallel > FF_ARRAY_ELEMS(attempts))
417  parallel = FF_ARRAY_ELEMS(attempts);
418 
419  print_address_list(h, addrs, "Original list of addresses");
420  // This mutates the list, but the head of the list is still the same
421  // element, so the caller, who owns the list, doesn't need to get
422  // an updated pointer.
423  interleave_addrinfo(addrs);
424  print_address_list(h, addrs, "Interleaved list of addresses");
425 
426  while (nb_attempts > 0 || addrs) {
427  // Start a new connection attempt, if possible.
428  if (nb_attempts < parallel && addrs) {
429  getnameinfo(addrs->ai_addr, addrs->ai_addrlen,
430  hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf),
432  av_log(h, AV_LOG_VERBOSE, "Starting connection attempt to %s port %s\n",
433  hostbuf, portbuf);
434  last_err = start_connect_attempt(&attempts[nb_attempts], &addrs,
435  timeout_ms_per_address, h,
436  customize_fd, customize_ctx);
437  if (last_err < 0) {
438  av_log(h, AV_LOG_VERBOSE, "Connected attempt failed: %s\n",
439  av_err2str(last_err));
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_log(h, AV_LOG_VERBOSE, "Connection attempt to %s port %s "
504  "failed: %s\n", hostbuf, portbuf, av_err2str(last_err));
505  closesocket(attempts[i].fd);
506  memmove(&attempts[i], &attempts[i + 1],
507  (nb_attempts - i - 1) * sizeof(*attempts));
508  memmove(&pfd[i], &pfd[i + 1],
509  (nb_attempts - i - 1) * sizeof(*pfd));
510  i--;
511  nb_attempts--;
512  }
513  }
514  for (i = 0; i < nb_attempts; i++)
515  closesocket(attempts[i].fd);
516  if (last_err >= 0)
517  last_err = AVERROR(ECONNREFUSED);
518  if (last_err != AVERROR_EXIT) {
519  av_log(h, AV_LOG_ERROR, "Connection to %s failed: %s\n",
520  h->filename, av_err2str(last_err));
521  }
522  return last_err;
523 }
524 
525 static int match_host_pattern(const char *pattern, const char *hostname)
526 {
527  int len_p, len_h;
528  if (!strcmp(pattern, "*"))
529  return 1;
530  // Skip a possible *. at the start of the pattern
531  if (pattern[0] == '*')
532  pattern++;
533  if (pattern[0] == '.')
534  pattern++;
535  len_p = strlen(pattern);
536  len_h = strlen(hostname);
537  if (len_p > len_h)
538  return 0;
539  // Simply check if the end of hostname is equal to 'pattern'
540  if (!strcmp(pattern, &hostname[len_h - len_p])) {
541  if (len_h == len_p)
542  return 1; // Exact match
543  if (hostname[len_h - len_p - 1] == '.')
544  return 1; // The matched substring is a domain and not just a substring of a domain
545  }
546  return 0;
547 }
548 
549 int ff_http_match_no_proxy(const char *no_proxy, const char *hostname)
550 {
551  char *buf, *start;
552  int ret = 0;
553  if (!no_proxy)
554  return 0;
555  if (!hostname)
556  return 0;
557  buf = av_strdup(no_proxy);
558  if (!buf)
559  return 0;
560  start = buf;
561  while (start) {
562  char *sep, *next = NULL;
563  start += strspn(start, " ,");
564  sep = start + strcspn(start, " ,");
565  if (*sep) {
566  next = sep + 1;
567  *sep = '\0';
568  }
569  if (match_host_pattern(start, hostname)) {
570  ret = 1;
571  break;
572  }
573  start = next;
574  }
575  av_free(buf);
576  return ret;
577 }
578 
579 void ff_log_net_error(void *ctx, int level, const char* prefix)
580 {
581  av_log(ctx, level, "%s: %s\n", prefix, av_err2str(ff_neterrno()));
582 }
ConnectionAttempt::fd
int fd
Definition: network.c:344
ConnectionAttempt::addr
struct addrinfo * addr
Definition: network.c:346
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:298
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:156
ff_gnutls_init
void ff_gnutls_init(void)
Definition: tls_gnutls.c:55
ff_log_net_error
void ff_log_net_error(void *ctx, int level, const char *prefix)
Definition: network.c:579
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:329
ff_network_close
void ff_network_close(void)
Definition: network.c:113
ConnectionAttempt::deadline_us
int64_t deadline_us
Definition: network.c:345
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:55
ff_tls_init
int ff_tls_init(void)
Definition: network.c:36
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:66
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:243
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:77
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:41
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
ctx
AVFormatContext * ctx
Definition: movenc.c:49
av_usleep
int av_usleep(unsigned usec)
Sleep for a period of time.
Definition: time.c:84
ff_http_match_no_proxy
int ff_http_match_no_proxy(const char *no_proxy, const char *hostname)
Definition: network.c:549
NULL
#define NULL
Definition: coverity.c:32
ff_is_multicast_address
int ff_is_multicast_address(struct sockaddr *addr)
Definition: network.c:142
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:255
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:75
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:225
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
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
ff_network_sleep_interruptible
int ff_network_sleep_interruptible(int64_t timeout, AVIOInterruptCB *int_cb)
Waits for up to 'timeout' microseconds.
Definition: network.c:95
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:308
ConnectionAttempt
Definition: network.c:343
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:404
ff_tls_deinit
void ff_tls_deinit(void)
Definition: network.c:46
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:207
tls.h
IN_MULTICAST
#define IN_MULTICAST(a)
Definition: network.h:241
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:272
mem.h
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:180
addrinfo
Definition: network.h:137
NEXT_ATTEMPT_DELAY_MS
#define NEXT_ATTEMPT_DELAY_MS
Definition: network.c:402
match_host_pattern
static int match_host_pattern(const char *pattern, const char *hostname)
Definition: network.c:525
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:351
ff_network_wait_fd
int ff_network_wait_fd(int fd, int write)
Definition: network.c:66