Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: "Rémi Denis-Courmont" <remi@remlab.net>
To: ffmpeg-devel@ffmpeg.org
Subject: Re: [FFmpeg-devel] [PATCH] libavformat/tcp: add local_addr/local_port for network option
Date: Thu, 02 Mar 2023 20:47:52 +0200
Message-ID: <2370995.qZ0jSbpfxB@basile.remlab.net> (raw)
In-Reply-To: <20230301154456.3407862-1-jack.wgm@gmail.com>

Le keskiviikkona 1. maaliskuuta 2023, 17.44.56 EET jackarain a écrit :
> Signed-off-by: jackarain <jack.wgm@gmail.com>
> ---
>  doc/protocols.texi    |  6 +++++
>  libavformat/network.c | 14 ++++++++----
>  libavformat/network.h |  2 +-
>  libavformat/tcp.c     | 53 ++++++++++++++++++++++++++++++++++++++++++-
>  4 files changed, 69 insertions(+), 6 deletions(-)
> 
> diff --git a/doc/protocols.texi b/doc/protocols.texi
> index 21ae6181a0..b3fad55591 100644
> --- a/doc/protocols.texi
> +++ b/doc/protocols.texi
> @@ -1882,6 +1882,12 @@ The list of supported options follows.
>  Listen for an incoming connection. 0 disables listen, 1 enables listen in
>  single client mode, 2 enables listen in multi-client mode. Default value is
> 0.
> 
> +@item local_addr=@var{addr}
> +Local IP address of a network interface used for tcp socket connect.
> +
> +@item local_port=@var{port}
> +Local port used for tcp socket connect.
> +
>  @item timeout=@var{microseconds}
>  Set raise error timeout, expressed in microseconds.
> 
> diff --git a/libavformat/network.c b/libavformat/network.c
> index 21e20b3e9a..de8b14be82 100644
> --- a/libavformat/network.c
> +++ b/libavformat/network.c
> @@ -356,7 +356,7 @@ struct ConnectionAttempt {
>  static int start_connect_attempt(struct ConnectionAttempt *attempt,
>                                   struct addrinfo **ptr, int timeout_ms,
>                                   URLContext *h,
> -                                 void (*customize_fd)(void *, int), void
> *customize_ctx) +                                 int (*customize_fd)(void
> *, int), void *customize_ctx) {
>      struct addrinfo *ai = *ptr;
>      int ret;
> @@ -371,8 +371,14 @@ static int start_connect_attempt(struct
> ConnectionAttempt *attempt,
> 
>      ff_socket_nonblock(attempt->fd, 1);
> 
> -    if (customize_fd)
> -        customize_fd(customize_ctx, attempt->fd);
> +    if (customize_fd) {
> +        ret = customize_fd(customize_ctx, attempt->fd);
> +        if (ret) {
> +            closesocket(attempt->fd);
> +            attempt->fd = -1;
> +            return ret;
> +        }
> +    }
> 
>      while ((ret = connect(attempt->fd, ai->ai_addr, ai->ai_addrlen))) {
>          ret = ff_neterrno();
> @@ -402,7 +408,7 @@ static int start_connect_attempt(struct
> ConnectionAttempt *attempt,
> 
>  int ff_connect_parallel(struct addrinfo *addrs, int timeout_ms_per_address,
> int parallel, URLContext *h, int *fd,
> -                        void (*customize_fd)(void *, int), void
> *customize_ctx) +                        int (*customize_fd)(void *, int),
> void *customize_ctx) {
>      struct ConnectionAttempt attempts[3];
>      struct pollfd pfd[3];
> diff --git a/libavformat/network.h b/libavformat/network.h
> index 71c49a73fb..8a8cbe672e 100644
> --- a/libavformat/network.h
> +++ b/libavformat/network.h
> @@ -336,6 +336,6 @@ void ff_log_net_error(void *ctx, int level, const char*
> prefix); */
>  int ff_connect_parallel(struct addrinfo *addrs, int timeout_ms_per_address,
> int parallel, URLContext *h, int *fd,
> -                        void (*customize_fd)(void *, int), void
> *customize_ctx); +                        int (*customize_fd)(void *, int),
> void *customize_ctx);
> 
>  #endif /* AVFORMAT_NETWORK_H */
> diff --git a/libavformat/tcp.c b/libavformat/tcp.c
> index a11ccbb913..a897174f6c 100644
> --- a/libavformat/tcp.c
> +++ b/libavformat/tcp.c
> @@ -36,6 +36,8 @@ typedef struct TCPContext {
>      const AVClass *class;
>      int fd;
>      int listen;
> +    char *local_port;
> +    char *local_addr;
>      int open_timeout;
>      int rw_timeout;
>      int listen_timeout;
> @@ -52,6 +54,8 @@ typedef struct TCPContext {
>  #define E AV_OPT_FLAG_ENCODING_PARAM
>  static const AVOption options[] = {
>      { "listen",          "Listen for incoming connections", 
> OFFSET(listen),         AV_OPT_TYPE_INT, { .i64 = 0 },     0,       2,     
>  .flags = D|E }, +    { "local_port",      "Local port",                   
>                      OFFSET(local_port),     AV_OPT_TYPE_STRING, { .str =
> NULL },     0,       0, .flags = D|E }, +    { "local_addr",      "Local
> address",                                      OFFSET(local_addr),    
> AV_OPT_TYPE_STRING, { .str = NULL },     0,       0, .flags = D|E }, {
> "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 }, { "listen_timeout",  "Connection awaiting timeout
> (in milliseconds)",      OFFSET(listen_timeout), AV_OPT_TYPE_INT, { .i64 =
> -1 },         -1, INT_MAX, .flags = D|E }, { "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,42 @@ static const AVClass tcp_class = {
>      .version    = LIBAVUTIL_VERSION_INT,
>  };
> 
> -static void customize_fd(void *ctx, int fd)
> +static int customize_fd(void *ctx, int fd)
>  {
>      TCPContext *s = ctx;
> +
> +    if (s->local_addr || s->local_port) {
> +        struct addrinfo hints = { 0 }, *ai, *cur_ai;
> +        int ret;
> +
> +        hints.ai_family = AF_UNSPEC;

That needs to match the socket protocol family, or bind() will fail.

> +        hints.ai_socktype = SOCK_STREAM;
> +
> +        ret = getaddrinfo(s->local_addr, s->local_port, &hints, &ai);
> +        if (ret) {
> +            av_log(ctx, AV_LOG_ERROR,
> +               "Failed to getaddrinfo local addr: %s port: %s err: %s\n",
> +                s->local_addr, s->local_port, gai_strerror(ret));
> +            return ret;
> +        }
> +
> +        cur_ai = ai;
> +        while (cur_ai) {
> +            ret = bind(fd, (struct sockaddr *)cur_ai->ai_addr,
> (int)cur_ai->ai_addrlen); +            if (ret)
> +                cur_ai = cur_ai->ai_next;
> +            else
> +                break;
> +        }
> +        freeaddrinfo(ai);
> +
> +        if (ret) {
> +            av_log(ctx, AV_LOG_ERROR,
> +                "Failed to bind local addr: %s port: %s err: %s\n",
> +                s->local_addr, s->local_port, gai_strerror(ret));
> +            return ret;
> +        }
> +    }
>      /* 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) {
> @@ -97,6 +134,8 @@ static void customize_fd(void *ctx, int fd)
>          }
>      }
>  #endif /* !HAVE_WINSOCK2_H */
> +
> +    return 0;
>  }
> 
>  /* return non zero if error */
> @@ -129,6 +168,18 @@ static int tcp_open(URLContext *h, const char *uri, int
> flags) if (buf == endptr)
>                  s->listen = 1;
>          }
> +        if (av_find_info_tag(buf, sizeof(buf), "local_port", p)) {
> +            av_freep(&s->local_port);
> +            s->local_port = av_strdup(buf);
> +            if (!s->local_addr)
> +                return AVERROR(ENOMEM);
> +        }
> +        if (av_find_info_tag(buf, sizeof(buf), "local_addr", p)) {
> +            av_freep(&s->local_addr);
> +            s->local_addr = av_strdup(buf);
> +            if (!s->local_addr)
> +                return AVERROR(ENOMEM);
> +        }
>          if (av_find_info_tag(buf, sizeof(buf), "timeout", p)) {
>              s->rw_timeout = strtol(buf, NULL, 10);
>          }


-- 
レミ・デニ-クールモン
http://www.remlab.net/



_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

  reply	other threads:[~2023-03-02 18:48 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-28 10:16 jack
2023-02-28 10:57 ` Nicolas George
2023-02-28 14:27   ` jackarain
2023-02-28 15:44 ` jackarain
2023-03-01 14:44   ` Anton Khirnov
2023-03-01 14:56     ` jackarain
2023-03-01 15:07     ` jackarain
2023-03-01 15:44       ` jackarain
2023-03-02 18:47         ` Rémi Denis-Courmont [this message]
2023-03-02 18:51           ` Nicolas George
2023-03-03  9:49             ` jackarain
2023-03-30 10:11               ` Anton Khirnov
2023-02-28 14:24 jackarain

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2370995.qZ0jSbpfxB@basile.remlab.net \
    --to=remi@remlab.net \
    --cc=ffmpeg-devel@ffmpeg.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git