Re: [FFmpeg-devel] [PATCH] avformat/rtpproto: add support for RTP/UDP socket reuse
> Because it is an useful option. Only not for this use case. > Because nobody noticed it was badly named when it was applied. > > > Why would it not apply to "rtp" also? > > Because nobody made the UDP socket context a child object of the RTP > context. So does it still makes sense to have a patch to pass through a RTP "reuseaddr" option to the underlying UDP URL "reuse" option? Documenting the good use cases of course (although I'd start using it for the wrong use case ;-)). If yes I'll resubmit the patch. I'm still planning to have a look on a proper (e.g using only one shared socket) implementation of rtcp-mux (easy one, I already have a PoC working) and RTP Bundle (tougher one). Regards -- Camille ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avformat/rtpproto: add support for RTP/UDP socket reuse
Why does the "reuse" option exists on the "udp" protocol in the first place? Why would it not apply to "rtp" also? Here is the original patch proposal on udp: http://ffmpeg.org/pipermail/ffmpeg-devel/2006-October/thread.html#18946 > Sure. But then that does not solve the problem of RTCP mux and SDP > bundle, which normally would use the exact same IP address and port > number on the local end (and also on the far end, if set). I confirm the requirement is to send several RTP streams with FFmpeg with identical proto/src_ip/src_port/dst_ip/dst_port. > > > It's not that simple. The semantics of REUSEPORT varies between Linux > and BSD. IIRC, REUSEPORT was originally meant by BSD to allow > multiple processes to listen on the same multicast group, but then > Linux redefined it with radically different semantics, for receive > load-balancing purpose. They added SO_REUSEPORT_LB in BSD to mimic the Linux behavior. > > Repeating myself, but I don't see how that solves the problem. You > don't need REUSEADDR for two sockets to send to the same remote > IP/port, and you cannot rely on it to send from the same local > IP/port. It *does* work, at least on Linux: I can send several RTP streams from the exact same local IP/port (and _to_ the same IP/port too but that's not a problem in general as you point it) with either REUSEADDR or REUSEPORT options set. Here are ffmpeg strace traces for local RTCP port == local RTP port. The command sends a video stream to the following RTP URL (RTP and are sent from the same local source port): rtp://127.0.0.1:4?localaddr=127.0.0.1=22300 =22300=4 without SO_REUSEPORT ... socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_IP) = 4 bind(4, {sa_family=AF_INET, sin_port=htons(22300), sin_addr=inet_addr("127.0.0.1")}, 16) = 0 getsockname(4, {sa_family=AF_INET, sin_port=htons(22300), in_addr=inet_addr("127.0.0.1")}, [128->16]) = 0 setsockopt(4, SOL_SOCKET, SO_SNDBUF, [32768], 4) = 0 socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_IP) = 5 bind(5, {sa_family=AF_INET, sin_port=htons(22300), in_addr=inet_addr("127.0.0.1")}, 16) = -1 EADDRINUSE (Address already in use) with SO_REUSEPORT = ... socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_IP) = 4 setsockopt(4, SOL_SOCKET, SO_REUSEPORT, [1], 4) = 0 bind(4, {sa_family=AF_INET, sin_port=htons(22300), sin_addr=inet_addr("127.0.0.1")}, 16) = 0 getsockname(4, {sa_family=AF_INET, sin_port=htons(22300), sin_addr=inet_addr("127.0.0.1")}, [128->16]) = 0 setsockopt(4, SOL_SOCKET, SO_SNDBUF, [32768], 4) = 0 socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_IP) = 5 setsockopt(5, SOL_SOCKET, SO_REUSEPORT, [1], 4) = 0 bind(5, {sa_family=AF_INET, sin_port=htons(22300), sin_addr=inet_addr("127.0.0.1")}, 16) = 0 Regards -- Camille ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avformat/rtpproto: add support for RTP/UDP socket reuse
Hi, I'm back on the topic. Thanks to all of you for your comments. > So I agree that SO_REUSEADDR is "absolutely not a hack"... if you use > it to recycle IP/port pair without waiting for the time-out. But > that's mainly of interest of listening/receiving sockets. That is indeed the case for TCP sockets, but as far as I know this does not apply to UDP as there is no TIME_WAIT state associated to datagram sockets. The classical use of this option would be for having a process binding on udp:0.0.0.0:1234 then another one binding on e.g. udp:192.168.1.10:1234 without triggering a "address in use" error. This is indeed a matter of listening socket. > If you use it to bind two concurrent sockets on the same IP/port > pair, then it is absolutely not just a hack but a platform-dependent > non-portable hack and a latent vulnerability in the OS (since one > process can hijack datagrams for another). The use of REUSEPORT instead of REUSEADDR is meant to mitigate this risk (but it's far from perfect). I definitely agree that using these options instead of refactoring or rewriting the RTP protocol to support RTP bundle and RTCP mux is a hack. I should take some time in the future to look into a proper solution. In the meantime, several people are looking for this feature: - http://ffmpeg.org/pipermail/ffmpeg-user/2018-September/041393.html - https://trac.ffmpeg.org/ticket/1774 - https://mediasoup.discourse.group/t/simulcast-with-plainrtptransport-and-ffmpeg/863 When the REUSEADDR option was added in FFmpeg UDP protocol what was the reason back then? And wouldn't this reason also apply for RTP? If we enable it for some legit reason, this could provide a (hacky and OS- dependent) solution for RTP bundle and RTCP mux, until the RTP protocol is properly refactored. Regards -- Camille ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avformat/rtpproto: add support for RTP/UDP socket reuse
On Sun, 2022-12-25 at 11:00 +0100, Rémi Denis-Courmont wrote: > Again, there is also REUSEPORT, which is what you'd want on Linux in > this case, but behaves differently on BSD and doesn't exist at all on > Windows (IIRC). That option is indeed preferable for security. It works equally good for the muxing use case, on Linux, with UDP sockets. I don't see why not using it instead, will do it in a new version of the patch. > So even for sending, I don't think this patch really works. REUSEADDR and thus this patch _are_ working well on Linux, with sockets that only send datagrams. It might behave differently on other systems though: I've read it is impossible to open two sockets having the same proto/src IP/src port/dst IP/dst port on BSD systems, but I don't have one handy. I will try it ASAP. What is the project's policy on options that are incompatible with some systems, or that behave differently? Regards -- Camille ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avformat/rtpproto: add support for RTP/UDP socket reuse
Hello, On Sat, 2022-12-24 at 13:36 +0200, Rémi Denis-Courmont wrote: > I don't see why you need an option for this. In parsing the SDP, it > should be self-evident if a given socket needs to be reused for RTCP- > mux or for SDP BUNDLE. I indeed disregarded the "receiving RTP streams" part, my bad. I should clarify that this patch is only useful for _sending_ bundled RTP streams and muxed RTCP sender reports. I am currently using this patch successfully in a simulcast streaming WebRTC infrastructure, that could not work without it. Only the AV_OPT_FLAG_ENCODING_PARAM should be set in the option's flags, as this is the only case that makes sense and properly works. Analyzing the corresponding SDP options and opening only one socket and demuxing in userspace should be the way to go for reading such streams as you pointed it. Again I must clarify that this use case is not covered, and will set the option's flags accordingly. Thanks for your feedback. -- Camille ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] avformat/rtpproto: add support for RTP/UDP socket reuse
Re-submitting because google webmail did not set the correct mime type, sorry for the noise. -- Camille From 998e1d3d79b416422e2b1d4f9a5ffb92062db256 Mon Sep 17 00:00:00 2001 From: Camille Oudot Date: Fri, 16 Dec 2022 15:30:02 +0100 Subject: [PATCH] avformat/rtpproto: add support for RTP/UDP socket reuse This patch introduces a "reuse" option over the RTP protocol. It simply passes the value to the underlying UDP protocol's "reuse" option. Some RTP peers expect multiple streams to come from the same IP/port, e.g. when RTP BUNDLE is involved (different streams sent from/to the same srcIP/srcPort/dspIp/dspPort tuple), or when rtcp-mux is involved (RTP and RTCP packets are muxed together). This patch allows ffmpeg to bundle RTP streams and mux RTP/RTCP together by setting the "reuse" option, and fiddling with the "localaddr", "localport", "localrtcpport" and "rtcpport" options. Signed-off-by: Camille Oudot --- Changelog | 1 + libavformat/rtpproto.c | 11 +++ 2 files changed, 12 insertions(+) diff --git a/Changelog b/Changelog index f3a6abb9cd..39b68f1702 100644 --- a/Changelog +++ b/Changelog @@ -28,6 +28,7 @@ version : - showcwt multimedia filter - corr video filter - adrc audio filter +- Add RTP protocol "reuse" option to allow UDP socket reuse version 5.1: diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c index b970901d01..e135907127 100644 --- a/libavformat/rtpproto.c +++ b/libavformat/rtpproto.c @@ -55,6 +55,7 @@ typedef struct RTPContext { int buffer_size; int rtcp_port, local_rtpport, local_rtcpport; int connect; +int reuse_socket; int pkt_size; int dscp; char *sources; @@ -74,6 +75,7 @@ static const AVOption options[] = { { "local_rtpport", "Local rtp port", OFFSET(local_rtpport), AV_OPT_TYPE_INT,{ .i64 = -1 },-1, INT_MAX, .flags = D|E }, { "local_rtcpport", "Local rtcp port", OFFSET(local_rtcpport), AV_OPT_TYPE_INT,{ .i64 = -1 },-1, INT_MAX, .flags = D|E }, { "connect","Connect socket", OFFSET(connect), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = D|E }, +{ "reuse", "Explicitly allow reusing UDP sockets", OFFSET(reuse_socket),AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = D|E }, { "write_to_source","Send packets to the source address of the latest received packet", OFFSET(write_to_source), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = D|E }, { "pkt_size", "Maximum packet size", OFFSET(pkt_size),AV_OPT_TYPE_INT,{ .i64 = -1 },-1, INT_MAX, .flags = D|E }, { "dscp", "DSCP class", OFFSET(dscp),AV_OPT_TYPE_INT,{ .i64 = -1 },-1, INT_MAX, .flags = D|E }, @@ -191,6 +193,8 @@ static void build_udp_url(RTPContext *s, url_add_option(buf, buf_size, "pkt_size=%d", s->pkt_size); if (s->connect) url_add_option(buf, buf_size, "connect=1"); +if (s->reuse_socket) +url_add_option(buf, buf_size, "reuse=1"); if (s->dscp >= 0) url_add_option(buf, buf_size, "dscp=%d", s->dscp); url_add_option(buf, buf_size, "fifo_size=0"); @@ -266,6 +270,13 @@ static int rtp_open(URLContext *h, const char *uri, int flags) if (av_find_info_tag(buf, sizeof(buf), "connect", p)) { s->connect = strtol(buf, NULL, 10); } +if (av_find_info_tag(buf, sizeof(buf), "reuse", p)) { +char *endptr = NULL; +s->reuse_socket = strtol(buf, , 10); +/* assume if no digits were found it is a request to enable it */ +if (buf == endptr) +s->reuse_socket = 1; +} if (av_find_info_tag(buf, sizeof(buf), "write_to_source", p)) { s->write_to_source = strtol(buf, NULL, 10); } -- 2.30.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] avformat/rtpproto: add support for RTP/UDP socket reuse
From 998e1d3d79b416422e2b1d4f9a5ffb92062db256 Mon Sep 17 00:00:00 2001 From: Camille Oudot Date: Fri, 16 Dec 2022 15:30:02 +0100 Subject: [PATCH] avformat/rtpproto: add support for RTP/UDP socket reuse This patch introduces a "reuse" option over the RTP protocol. It simply passes the value to the underlying UDP protocol's "reuse" option. Some RTP peers expect multiple streams to come from the same IP/port, e.g. when RTP BUNDLE is involved (different streams sent from/to the same srcIP/srcPort/dspIp/dspPort tuple), or when rtcp-mux is involved (RTP and RTCP packets are muxed together). This patch allows ffmpeg to bundle RTP streams and mux RTP/RTCP together by setting the "reuse" option, and fiddling with the "localaddr", "localport", "localrtcpport" and "rtcpport" options. Signed-off-by: Camille Oudot --- Changelog | 1 + libavformat/rtpproto.c | 11 +++ 2 files changed, 12 insertions(+) diff --git a/Changelog b/Changelog index f3a6abb9cd..39b68f1702 100644 --- a/Changelog +++ b/Changelog @@ -28,6 +28,7 @@ version : - showcwt multimedia filter - corr video filter - adrc audio filter +- Add RTP protocol "reuse" option to allow UDP socket reuse version 5.1: diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c index b970901d01..e135907127 100644 --- a/libavformat/rtpproto.c +++ b/libavformat/rtpproto.c @@ -55,6 +55,7 @@ typedef struct RTPContext { int buffer_size; int rtcp_port, local_rtpport, local_rtcpport; int connect; +int reuse_socket; int pkt_size; int dscp; char *sources; @@ -74,6 +75,7 @@ static const AVOption options[] = { { "local_rtpport", "Local rtp port", OFFSET(local_rtpport), AV_OPT_TYPE_INT,{ .i64 = -1 },-1, INT_MAX, .flags = D|E }, { "local_rtcpport", "Local rtcp port", OFFSET(local_rtcpport), AV_OPT_TYPE_INT,{ .i64 = -1 },-1, INT_MAX, .flags = D|E }, { "connect","Connect socket", OFFSET(connect), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = D|E }, +{ "reuse", "Explicitly allow reusing UDP sockets", OFFSET(reuse_socket),AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = D|E }, { "write_to_source","Send packets to the source address of the latest received packet", OFFSET(write_to_source), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = D|E }, { "pkt_size", "Maximum packet size", OFFSET(pkt_size),AV_OPT_TYPE_INT,{ .i64 = -1 },-1, INT_MAX, .flags = D|E }, { "dscp", "DSCP class", OFFSET(dscp),AV_OPT_TYPE_INT,{ .i64 = -1 },-1, INT_MAX, .flags = D|E }, @@ -191,6 +193,8 @@ static void build_udp_url(RTPContext *s, url_add_option(buf, buf_size, "pkt_size=%d", s->pkt_size); if (s->connect) url_add_option(buf, buf_size, "connect=1"); +if (s->reuse_socket) +url_add_option(buf, buf_size, "reuse=1"); if (s->dscp >= 0) url_add_option(buf, buf_size, "dscp=%d", s->dscp); url_add_option(buf, buf_size, "fifo_size=0"); @@ -266,6 +270,13 @@ static int rtp_open(URLContext *h, const char *uri, int flags) if (av_find_info_tag(buf, sizeof(buf), "connect", p)) { s->connect = strtol(buf, NULL, 10); } +if (av_find_info_tag(buf, sizeof(buf), "reuse", p)) { +char *endptr = NULL; +s->reuse_socket = strtol(buf, , 10); +/* assume if no digits were found it is a request to enable it */ +if (buf == endptr) +s->reuse_socket = 1; +} if (av_find_info_tag(buf, sizeof(buf), "write_to_source", p)) { s->write_to_source = strtol(buf, NULL, 10); } -- 2.30.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".