From 21a569f3022e968d74bfde4d1bfff8dab5edd41c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin@martin.st> Date: Thu, 6 Jan 2011 15:16:50 +0000 Subject: [PATCH] udp: Allow specifying the connect option in udp_set_remote_url, too If the remote address is updated later with this function, the caller shouldn't set the connect option until in this call. Originally committed as revision 26245 to svn://svn.ffmpeg.org/ffmpeg/trunk --- doc/protocols.texi | 4 ++++ libavformat/udp.c | 18 +++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/doc/protocols.texi b/doc/protocols.texi index b76e45c3d3f..600f4704582 100644 --- a/doc/protocols.texi +++ b/doc/protocols.texi @@ -415,9 +415,13 @@ set the time to live value (for multicast only) @item connect=@var{1|0} Initialize the UDP socket with @code{connect()}. In this case, the destination address can't be changed with udp_set_remote_url later. +If the destination address isn't known at the start, this option can +be specified in udp_set_remote_url, too. This allows finding out the source address for the packets with getsockname, and makes writes return with AVERROR(ECONNREFUSED) if "destination unreachable" is received. +For receiving, this gives the benefit of only receiving packets from +the specified peer address/port. @end table Some usage examples of the udp protocol with @file{ffmpeg} follow. diff --git a/libavformat/udp.c b/libavformat/udp.c index b998086407e..0b62c6da2df 100644 --- a/libavformat/udp.c +++ b/libavformat/udp.c @@ -245,8 +245,9 @@ static int udp_port(struct sockaddr_storage *addr, int addr_len) int udp_set_remote_url(URLContext *h, const char *uri) { UDPContext *s = h->priv_data; - char hostname[256]; + char hostname[256], buf[10]; int port; + const char *p; av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri); @@ -256,6 +257,21 @@ int udp_set_remote_url(URLContext *h, const char *uri) return AVERROR(EIO); } s->is_multicast = ff_is_multicast_address((struct sockaddr*) &s->dest_addr); + p = strchr(uri, '?'); + if (p) { + if (find_info_tag(buf, sizeof(buf), "connect", p)) { + int was_connected = s->is_connected; + s->is_connected = strtol(buf, NULL, 10); + if (s->is_connected && !was_connected) { + if (connect(s->udp_fd, (struct sockaddr *) &s->dest_addr, + s->dest_addr_len)) { + s->is_connected = 0; + av_log(NULL, AV_LOG_ERROR, "connect: %s\n", strerror(errno)); + return AVERROR(EIO); + } + } + } + } return 0; } -- GitLab