History

libavformat/tcp: add local_addr/local_port for network option

jackarain committed 3 years ago

Commit 4d216651 parent 0684e585 files · +69 −8Browse files

Unified · Split

5 files
  1. doc/protocols.texi +6 −0
  2. libavformat/network.c +10 −4
  3. libavformat/network.h +1 −1
  4. libavformat/tcp.c +51 −2
  5. libavformat/version.h +1 −1
doc/protocols.texi+6−0
@@ -1882,6 +1882,12 @@ The list of supported options follows. · 1881 unmodified lines
1882Listen for an incoming connection. 0 disables listen, 1 enables listen in1882Listen for an incoming connection. 0 disables listen, 1 enables listen in
1883single client mode, 2 enables listen in multi-client mode. Default value is 0.1883single client mode, 2 enables listen in multi-client mode. Default value is 0.
1884 1884
1885@item local_addr=@var{addr}
1886Local IP address of a network interface used for tcp socket connect.
1887
1888@item local_port=@var{port}
1889Local port used for tcp socket connect.
1890
1885@item timeout=@var{microseconds}1891@item timeout=@var{microseconds}
1886Set raise error timeout, expressed in microseconds.1892Set raise error timeout, expressed in microseconds.
1887 1893
libavformat/network.c+10−4
@@ -356,7 +356,7 @@ struct ConnectionAttempt { · 355 unmodified lines
356static int start_connect_attempt(struct ConnectionAttempt *attempt,356static int start_connect_attempt(struct ConnectionAttempt *attempt,
357 struct addrinfo **ptr, int timeout_ms,357 struct addrinfo **ptr, int timeout_ms,
358 URLContext *h,358 URLContext *h,
359 void (*customize_fd)(void *, int), void *customize_ctx)359 int (*customize_fd)(void *, int, int), void *customize_ctx)
360{360{
361 struct addrinfo *ai = *ptr;361 struct addrinfo *ai = *ptr;
362 int ret;362 int ret;
@@ -371,8 +371,14 @@ static int start_connect_attempt(struct ConnectionAttempt *attempt, · 8 unmodified lines
371 371
372 ff_socket_nonblock(attempt->fd, 1);372 ff_socket_nonblock(attempt->fd, 1);
373 373
374 if (customize_fd)374 if (customize_fd) {
375 customize_fd(customize_ctx, attempt->fd);375 ret = customize_fd(customize_ctx, attempt->fd, ai->ai_family);
376 if (ret) {
377 closesocket(attempt->fd);
378 attempt->fd = -1;
379 return ret;
380 }
381 }
376 382
377 while ((ret = connect(attempt->fd, ai->ai_addr, ai->ai_addrlen))) {383 while ((ret = connect(attempt->fd, ai->ai_addr, ai->ai_addrlen))) {
378 ret = ff_neterrno();384 ret = ff_neterrno();
@@ -402,7 +408,7 @@ static int start_connect_attempt(struct ConnectionAttempt *attempt, · 23 unmodified lines
402 408
403int ff_connect_parallel(struct addrinfo *addrs, int timeout_ms_per_address,409int ff_connect_parallel(struct addrinfo *addrs, int timeout_ms_per_address,
404 int parallel, URLContext *h, int *fd,410 int parallel, URLContext *h, int *fd,
405 void (*customize_fd)(void *, int), void *customize_ctx)411 int (*customize_fd)(void *, int, int), void *customize_ctx)
406{412{
407 struct ConnectionAttempt attempts[3];413 struct ConnectionAttempt attempts[3];
408 struct pollfd pfd[3];414 struct pollfd pfd[3];
libavformat/network.h+1−1
@@ -336,6 +336,6 @@ void ff_log_net_error(void *ctx, int level, const char* prefix); · 335 unmodified lines
336 */336 */
337int ff_connect_parallel(struct addrinfo *addrs, int timeout_ms_per_address,337int ff_connect_parallel(struct addrinfo *addrs, int timeout_ms_per_address,
338 int parallel, URLContext *h, int *fd,338 int parallel, URLContext *h, int *fd,
339 void (*customize_fd)(void *, int), void *customize_ctx);339 int (*customize_fd)(void *, int, int), void *customize_ctx);
340 340
341#endif /* AVFORMAT_NETWORK_H */341#endif /* AVFORMAT_NETWORK_H */
libavformat/tcp.c+51−2
@@ -36,6 +36,8 @@ typedef struct TCPContext { · 35 unmodified lines
36 const AVClass *class;36 const AVClass *class;
37 int fd;37 int fd;
38 int listen;38 int listen;
39 char *local_port;
40 char *local_addr;
39 int open_timeout;41 int open_timeout;
40 int rw_timeout;42 int rw_timeout;
41 int listen_timeout;43 int listen_timeout;
@@ -52,6 +54,8 @@ typedef struct TCPContext { · 10 unmodified lines
52#define E AV_OPT_FLAG_ENCODING_PARAM54#define E AV_OPT_FLAG_ENCODING_PARAM
53static const AVOption options[] = {55static const AVOption options[] = {
54 { "listen", "Listen for incoming connections", OFFSET(listen), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, .flags = D|E },56 { "listen", "Listen for incoming connections", OFFSET(listen), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, .flags = D|E },
57 { "local_port", "Local port", OFFSET(local_port), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, .flags = D|E },
58 { "local_addr", "Local address", OFFSET(local_addr), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, .flags = D|E },
55 { "timeout", "set timeout (in microseconds) of socket I/O operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },59 { "timeout", "set timeout (in microseconds) of socket I/O operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
56 { "listen_timeout", "Connection awaiting timeout (in milliseconds)", OFFSET(listen_timeout), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },60 { "listen_timeout", "Connection awaiting timeout (in milliseconds)", OFFSET(listen_timeout), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
57 { "send_buffer_size", "Socket send buffer size (in bytes)", OFFSET(send_buffer_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },61 { "send_buffer_size", "Socket send buffer size (in bytes)", OFFSET(send_buffer_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
@@ -70,9 +74,40 @@ static const AVClass tcp_class = { · 12 unmodified lines
70 .version = LIBAVUTIL_VERSION_INT,74 .version = LIBAVUTIL_VERSION_INT,
71};75};
72 76
73static void customize_fd(void *ctx, int fd)77static int customize_fd(void *ctx, int fd, int family)
74{78{
75 TCPContext *s = ctx;79 TCPContext *s = ctx;
80
81 if (s->local_addr || s->local_port) {
82 struct addrinfo hints = { 0 }, *ai, *cur_ai;
83 int ret;
84
85 hints.ai_family = family;
86 hints.ai_socktype = SOCK_STREAM;
87
88 ret = getaddrinfo(s->local_addr, s->local_port, &hints, &ai);
89 if (ret) {
90 av_log(ctx, AV_LOG_ERROR,
91 "Failed to getaddrinfo local addr: %s port: %s err: %s\n",
92 s->local_addr, s->local_port, gai_strerror(ret));
93 return ret;
94 }
95
96 cur_ai = ai;
97 while (cur_ai) {
98 ret = bind(fd, (struct sockaddr *)cur_ai->ai_addr, (int)cur_ai->ai_addrlen);
99 if (ret)
100 cur_ai = cur_ai->ai_next;
101 else
102 break;
103 }
104 freeaddrinfo(ai);
105
106 if (ret) {
107 ff_log_net_error(ctx, AV_LOG_ERROR, "bind local failed");
108 return ret;
109 }
110 }
76 /* Set the socket's send or receive buffer sizes, if specified.111 /* Set the socket's send or receive buffer sizes, if specified.
77 If unspecified or setting fails, system default is used. */112 If unspecified or setting fails, system default is used. */
78 if (s->recv_buffer_size > 0) {113 if (s->recv_buffer_size > 0) {
@@ -97,6 +132,8 @@ static void customize_fd(void *ctx, int fd) · 18 unmodified lines
97 }132 }
98 }133 }
99#endif /* !HAVE_WINSOCK2_H */134#endif /* !HAVE_WINSOCK2_H */
135
136 return 0;
100}137}
101 138
102/* return non zero if error */139/* return non zero if error */
@@ -129,6 +166,18 @@ static int tcp_open(URLContext *h, const char *uri, int flags) · 26 unmodified lines
129 if (buf == endptr)166 if (buf == endptr)
130 s->listen = 1;167 s->listen = 1;
131 }168 }
169 if (av_find_info_tag(buf, sizeof(buf), "local_port", p)) {
170 av_freep(&s->local_port);
171 s->local_port = av_strdup(buf);
172 if (!s->local_addr)
173 return AVERROR(ENOMEM);
174 }
175 if (av_find_info_tag(buf, sizeof(buf), "local_addr", p)) {
176 av_freep(&s->local_addr);
177 s->local_addr = av_strdup(buf);
178 if (!s->local_addr)
179 return AVERROR(ENOMEM);
180 }
132 if (av_find_info_tag(buf, sizeof(buf), "timeout", p)) {181 if (av_find_info_tag(buf, sizeof(buf), "timeout", p)) {
133 s->rw_timeout = strtol(buf, NULL, 10);182 s->rw_timeout = strtol(buf, NULL, 10);
134 }183 }
@@ -183,7 +232,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags) · 48 unmodified lines
183 }232 }
184 if (fd < 0)233 if (fd < 0)
185 goto fail1;234 goto fail1;
186 customize_fd(s, fd);235 customize_fd(s, fd, cur_ai->ai_family);
187 }236 }
188 237
189 if (s->listen == 2) {238 if (s->listen == 2) {
libavformat/version.h+1−1
@@ -32,7 +32,7 @@ · 31 unmodified lines
32#include "version_major.h"32#include "version_major.h"
33 33
34#define LIBAVFORMAT_VERSION_MINOR 434#define LIBAVFORMAT_VERSION_MINOR 4
35#define LIBAVFORMAT_VERSION_MICRO 10035#define LIBAVFORMAT_VERSION_MICRO 101
36 36
37#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \37#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
38 LIBAVFORMAT_VERSION_MINOR, \38 LIBAVFORMAT_VERSION_MINOR, \

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t