ffmpeg | branch: master | James Almer <jamr...@gmail.com> | Tue Sep 11 13:54:59 2018 -0300| [ef71ef5f30ddf1cd61e46628a04608892caf76d2] | committer: James Almer
Merge commit '8c76bfacf663ff71cee5264a74d0f9c86addd325' * commit '8c76bfacf663ff71cee5264a74d0f9c86addd325': tcp: Use ff_connect_parallel for RFC 8305 style connecting Merged-by: James Almer <jamr...@gmail.com> > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=ef71ef5f30ddf1cd61e46628a04608892caf76d2 --- libavformat/tcp.c | 84 ++++++++++++++++++++++++------------------------------- 1 file changed, 36 insertions(+), 48 deletions(-) diff --git a/libavformat/tcp.c b/libavformat/tcp.c index 8bff9a3867..ea41f2e986 100644 --- a/libavformat/tcp.c +++ b/libavformat/tcp.c @@ -70,6 +70,27 @@ static const AVClass tcp_class = { .version = LIBAVUTIL_VERSION_INT, }; +static void customize_fd(void *ctx, int fd) +{ + TCPContext *s = ctx; + /* Set the socket's send or receive buffer sizes, if specified. + If unspecified or setting fails, system default is used. */ + if (s->recv_buffer_size > 0) { + setsockopt (fd, SOL_SOCKET, SO_RCVBUF, &s->recv_buffer_size, sizeof (s->recv_buffer_size)); + } + if (s->send_buffer_size > 0) { + setsockopt (fd, SOL_SOCKET, SO_SNDBUF, &s->send_buffer_size, sizeof (s->send_buffer_size)); + } + if (s->tcp_nodelay > 0) { + setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &s->tcp_nodelay, sizeof (s->tcp_nodelay)); + } +#if !HAVE_WINSOCK2_H + if (s->tcp_mss > 0) { + setsockopt (fd, IPPROTO_TCP, TCP_MAXSEG, &s->tcp_mss, sizeof (s->tcp_mss)); + } +#endif /* !HAVE_WINSOCK2_H */ +} + /* return non zero if error */ static int tcp_open(URLContext *h, const char *uri, int flags) { @@ -129,7 +150,6 @@ static int tcp_open(URLContext *h, const char *uri, int flags) cur_ai = ai; - restart: #if HAVE_STRUCT_SOCKADDR_IN6 // workaround for IOS9 getaddrinfo in IPv6 only network use hardcode IPv4 address can not resolve port number. if (cur_ai->ai_family == AF_INET6){ @@ -140,38 +160,20 @@ static int tcp_open(URLContext *h, const char *uri, int flags) } #endif - fd = ff_socket(cur_ai->ai_family, - cur_ai->ai_socktype, - cur_ai->ai_protocol); - if (fd < 0) { - ret = ff_neterrno(); - goto fail; - } - - /* Set the socket's send or receive buffer sizes, if specified. - If unspecified or setting fails, system default is used. */ - if (s->recv_buffer_size > 0) { - if (setsockopt (fd, SOL_SOCKET, SO_RCVBUF, &s->recv_buffer_size, sizeof (s->recv_buffer_size))) { - ff_log_net_error(h, AV_LOG_WARNING, "setsockopt(SO_RCVBUF)"); - } - } - if (s->send_buffer_size > 0) { - if (setsockopt (fd, SOL_SOCKET, SO_SNDBUF, &s->send_buffer_size, sizeof (s->send_buffer_size))) { - ff_log_net_error(h, AV_LOG_WARNING, "setsockopt(SO_SNDBUF)"); - } - } - if (s->tcp_nodelay > 0) { - if (setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &s->tcp_nodelay, sizeof (s->tcp_nodelay))) { - ff_log_net_error(h, AV_LOG_WARNING, "setsockopt(TCP_NODELAY)"); - } - } -#if !HAVE_WINSOCK2_H - if (s->tcp_mss > 0) { - if (setsockopt (fd, IPPROTO_TCP, TCP_MAXSEG, &s->tcp_mss, sizeof (s->tcp_mss))) { - ff_log_net_error(h, AV_LOG_WARNING, "setsockopt(TCP_MAXSEG)"); + if (s->listen > 0) { + while (cur_ai && fd < 0) { + fd = ff_socket(cur_ai->ai_family, + cur_ai->ai_socktype, + cur_ai->ai_protocol); + if (fd < 0) { + ret = ff_neterrno(); + cur_ai = cur_ai->ai_next; + } } + if (fd < 0) + goto fail1; + customize_fd(s, fd); } -#endif /* !HAVE_WINSOCK2_H */ if (s->listen == 2) { // multi-client @@ -185,14 +187,9 @@ static int tcp_open(URLContext *h, const char *uri, int flags) // Socket descriptor already closed here. Safe to overwrite to client one. fd = ret; } else { - if ((ret = ff_listen_connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen, - s->open_timeout / 1000, h, !!cur_ai->ai_next)) < 0) { - - if (ret == AVERROR_EXIT) - goto fail1; - else - goto fail; - } + ret = ff_connect_parallel(ai, s->open_timeout / 1000, 3, h, &fd, customize_fd, s); + if (ret < 0) + goto fail1; } h->is_streamed = 1; @@ -201,15 +198,6 @@ static int tcp_open(URLContext *h, const char *uri, int flags) freeaddrinfo(ai); return 0; - fail: - if (cur_ai->ai_next) { - /* Retry with the next sockaddr */ - cur_ai = cur_ai->ai_next; - if (fd >= 0) - closesocket(fd); - ret = 0; - goto restart; - } fail1: if (fd >= 0) closesocket(fd); ====================================================================== diff --cc libavformat/tcp.c index 8bff9a3867,7044d44f06..ea41f2e986 --- a/libavformat/tcp.c +++ b/libavformat/tcp.c @@@ -70,6 -55,6 +70,27 @@@ static const AVClass tcp_class = .version = LIBAVUTIL_VERSION_INT, }; ++static void customize_fd(void *ctx, int fd) ++{ ++ TCPContext *s = ctx; ++ /* Set the socket's send or receive buffer sizes, if specified. ++ If unspecified or setting fails, system default is used. */ ++ if (s->recv_buffer_size > 0) { ++ setsockopt (fd, SOL_SOCKET, SO_RCVBUF, &s->recv_buffer_size, sizeof (s->recv_buffer_size)); ++ } ++ if (s->send_buffer_size > 0) { ++ setsockopt (fd, SOL_SOCKET, SO_SNDBUF, &s->send_buffer_size, sizeof (s->send_buffer_size)); ++ } ++ if (s->tcp_nodelay > 0) { ++ setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &s->tcp_nodelay, sizeof (s->tcp_nodelay)); ++ } ++#if !HAVE_WINSOCK2_H ++ if (s->tcp_mss > 0) { ++ setsockopt (fd, IPPROTO_TCP, TCP_MAXSEG, &s->tcp_mss, sizeof (s->tcp_mss)); ++ } ++#endif /* !HAVE_WINSOCK2_H */ ++} ++ /* return non zero if error */ static int tcp_open(URLContext *h, const char *uri, int flags) { @@@ -129,70 -108,28 +150,46 @@@ cur_ai = ai; - restart: - if (s->listen) { +#if HAVE_STRUCT_SOCKADDR_IN6 + // workaround for IOS9 getaddrinfo in IPv6 only network use hardcode IPv4 address can not resolve port number. + if (cur_ai->ai_family == AF_INET6){ + struct sockaddr_in6 * sockaddr_v6 = (struct sockaddr_in6 *)cur_ai->ai_addr; + if (!sockaddr_v6->sin6_port){ + sockaddr_v6->sin6_port = htons(port); + } + } +#endif + - fd = ff_socket(cur_ai->ai_family, - cur_ai->ai_socktype, - cur_ai->ai_protocol); - if (fd < 0) { - ret = ff_neterrno(); - goto fail; - } - - /* Set the socket's send or receive buffer sizes, if specified. - If unspecified or setting fails, system default is used. */ - if (s->recv_buffer_size > 0) { - if (setsockopt (fd, SOL_SOCKET, SO_RCVBUF, &s->recv_buffer_size, sizeof (s->recv_buffer_size))) { - ff_log_net_error(h, AV_LOG_WARNING, "setsockopt(SO_RCVBUF)"); - } - } - if (s->send_buffer_size > 0) { - if (setsockopt (fd, SOL_SOCKET, SO_SNDBUF, &s->send_buffer_size, sizeof (s->send_buffer_size))) { - ff_log_net_error(h, AV_LOG_WARNING, "setsockopt(SO_SNDBUF)"); - } - } - if (s->tcp_nodelay > 0) { - if (setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &s->tcp_nodelay, sizeof (s->tcp_nodelay))) { - ff_log_net_error(h, AV_LOG_WARNING, "setsockopt(TCP_NODELAY)"); - } - } - #if !HAVE_WINSOCK2_H - if (s->tcp_mss > 0) { - if (setsockopt (fd, IPPROTO_TCP, TCP_MAXSEG, &s->tcp_mss, sizeof (s->tcp_mss))) { - ff_log_net_error(h, AV_LOG_WARNING, "setsockopt(TCP_MAXSEG)"); ++ if (s->listen > 0) { + while (cur_ai && fd < 0) { + fd = ff_socket(cur_ai->ai_family, + cur_ai->ai_socktype, + cur_ai->ai_protocol); + if (fd < 0) { + ret = ff_neterrno(); + cur_ai = cur_ai->ai_next; + } } + if (fd < 0) + goto fail1; ++ customize_fd(s, fd); + } - #endif /* !HAVE_WINSOCK2_H */ + if (s->listen == 2) { + // multi-client + if ((ret = ff_listen(fd, cur_ai->ai_addr, cur_ai->ai_addrlen)) < 0) + goto fail1; + } else if (s->listen == 1) { + // single client if ((ret = ff_listen_bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen, - s->listen_timeout, h)) < 0) { + s->listen_timeout, h)) < 0) goto fail1; - } + // Socket descriptor already closed here. Safe to overwrite to client one. fd = ret; } else { - if ((ret = ff_listen_connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen, - s->open_timeout / 1000, h, !!cur_ai->ai_next)) < 0) { - - if (ret == AVERROR_EXIT) - goto fail1; - else - goto fail; - } - ret = ff_connect_parallel(ai, s->timeout, 3, h, &fd, NULL, NULL); ++ ret = ff_connect_parallel(ai, s->open_timeout / 1000, 3, h, &fd, customize_fd, s); + if (ret < 0) + goto fail1; } h->is_streamed = 1; _______________________________________________ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog