[1/3] rtsp: Use a random offset for trying to open UDP ports for RTP

Message ID 1327095958-15527-1-git-send-email-martin@martin.st
State Superseded
Headers show

Commit Message

Martin Storsjö Jan. 20, 2012, 9:45 p.m.
From: Dmitry Volyntsev <xeioexception@gmail.com>

This avoids (for all practical cases) the issue of reusing
the same UDP port as for an earlier connection. If the remote
doesn't know the previous session was closed, he might keep
on sending packets to that port. If we always start off trying
to open the same UDP port, we might get those packets intermixed
with the new ones we want.

This is occasionally an issue when testing RTSP stuff with
DSS, perhaps also with other servers.

If the random offset happens to be at the very end of the range,
we might only be trying a small number of ports before giving up.
(Currently this is solved by extending the range to contain
much more ports.)

Alternative solutions would be to only choose a random offset in
e.g. the lower half of the range, or to make the testing wrap
around so the full range still is tested.
---
 libavformat/rtsp.c |    7 +++++--
 libavformat/rtsp.h |    2 +-
 2 files changed, 6 insertions(+), 3 deletions(-)

Comments

Luca Barbato Jan. 20, 2012, 10:37 p.m. | #1
On 20/01/12 13:45, Martin Storsjö wrote:
> +    port_off = av_get_random_seed() % (RTSP_RTP_PORT_MAX - RTSP_RTP_PORT_MIN);

Not sure if it might have an impact on performance and/or randomness
availability.

lu
Martin Storsjö Jan. 20, 2012, 10:38 p.m. | #2
On Fri, 20 Jan 2012, Luca Barbato wrote:

> On 20/01/12 13:45, Martin Storsjö wrote:
>> +    port_off = av_get_random_seed() % (RTSP_RTP_PORT_MAX - RTSP_RTP_PORT_MIN);
>
> Not sure if it might have an impact on performance and/or randomness
> availability.

Shouldn't be an issue, av_get_random_seed() uses urandom which shouldn't 
block.

// Martin

Patch

diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 2858a9a..3810e0c 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -1103,7 +1103,7 @@  int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
                               int lower_transport, const char *real_challenge)
 {
     RTSPState *rt = s->priv_data;
-    int rtx = 0, j, i, err, interleave = 0;
+    int rtx = 0, j, i, err, interleave = 0, port_off;
     RTSPStream *rtsp_st;
     RTSPMessageHeader reply1, *reply = &reply1;
     char cmd[2048];
@@ -1120,8 +1120,11 @@  int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
     /* for each stream, make the setup request */
     /* XXX: we assume the same server is used for the control of each
      * RTSP stream */
+    port_off = av_get_random_seed() % (RTSP_RTP_PORT_MAX - RTSP_RTP_PORT_MIN);
+    /* even random offset */
+    port_off -= port_off & 0x01;
 
-    for (j = RTSP_RTP_PORT_MIN, i = 0; i < rt->nb_rtsp_streams; ++i) {
+    for (j = RTSP_RTP_PORT_MIN + port_off, i = 0; i < rt->nb_rtsp_streams; ++i) {
         char transport[2048];
 
         /*
diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h
index 662407f..777125e 100644
--- a/libavformat/rtsp.h
+++ b/libavformat/rtsp.h
@@ -70,7 +70,7 @@  enum RTSPControlTransport {
 #define RTSP_DEFAULT_NB_AUDIO_CHANNELS 1
 #define RTSP_DEFAULT_AUDIO_SAMPLERATE 44100
 #define RTSP_RTP_PORT_MIN 5000
-#define RTSP_RTP_PORT_MAX 10000
+#define RTSP_RTP_PORT_MAX 65000
 
 /**
  * This describes a single item in the "Transport:" line of one stream as