[vlc-devel] [PATCH 3/3] access/udp: reduce mtu amount on initial packets

Ilkka Ollakka ileoo at videolan.org
Mon Oct 15 20:30:53 CEST 2018


In this approach, mtu is setted to high on start, and if received data
is less than 1500 and mtu is higher than that, we adjust mtu on future
packets to be smaller. In majority of cases in UDP streaming, packet
size is usually quite constant, so it should work, even if it's not
generic solution to udp packet receiving.

Also in case of truncing packets on other than linux systems, use same
assumption and peek the next data amount to adjust mtu for future
packets. We don't call PEEK on all the cases, as it would be unnecessary
system call on majority of the calls.

ref #20952 and other similar tickets.
---
 modules/access/udp.c | 40 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 37 insertions(+), 3 deletions(-)

diff --git a/modules/access/udp.c b/modules/access/udp.c
index b5ba292e48..7648b2ebc6 100644
--- a/modules/access/udp.c
+++ b/modules/access/udp.c
@@ -168,7 +168,7 @@ static int Open( vlc_object_t *p_this )
         return VLC_EGENERIC;
     }
 
-    sys->mtu = 7 * 188;
+    sys->mtu = 65536;
 
     sys->timeout = var_InheritInteger( p_access, "udp-timeout");
     if( sys->timeout > 0)
@@ -262,6 +262,7 @@ static block_t *BlockUDP(stream_t *access, bool *restrict eof)
             goto skip;
      }
 
+
     ssize_t len = recvmsg(sys->fd, &msg, trunc_flag);
 
     if (len < 0)
@@ -271,14 +272,47 @@ skip:
         return NULL;
     }
 
-    if (msg.msg_flags & trunc_flag )
+    /* Check if received amount is other side of ethernet mtu amount of 1500,
+       and reduce mtu if it's so. Failsafe to keep mtu still atleast 1000 bytes.
+       With this approach, we can start with way higher than needed mtu for 1 packet
+       and with first packets, it should adjust to reasonable size.
+       Assuming that most cases in real world the udp packet size don't fluctuate
+       huge amounts on size in streaming. And on those cases the MSG_TRUNC should
+       then readjust.
+     */
+
+    if (unlikely((sys->mtu > 1500) && (len > 1000) && (len < 1500)))
     {
+        msg_Dbg(access, "adjusting MTU from %zd to %zu", sys->mtu, len);
+        sys->mtu = len;
+    }
+
+#ifdef MSG_TRUNC
+    if (msg.msg_flags & MSG_TRUNC)
+    {
+        pkt->i_flags |= BLOCK_FLAG_CORRUPTED;
+        /* On linux systems MSG_TRUNC tells the available data,
+           on other cases, I think we need to peek to get how much
+           there would be availabled in case of trunced message.
+           In MSG_PEEK case, assumption is also, that in real world
+           the size don't fluctuate huge amounts in streaming.
+         */
+#ifdef __linux__
         msg_Err(access, "%zd bytes packet truncated (MTU was %zu)",
                 len, sys->mtu);
-        pkt->i_flags |= BLOCK_FLAG_CORRUPTED;
         sys->mtu = len;
+#else
+        sys->mtu = recv(sys->fd, pkt->p_buffer, sys->mtu, MSG_PEEK|MSG_TRUNC);
+        /* In this case, len is old mtu and max received amount, mtu is the
+         * peeked value, that's why they are otherway around in this compared
+         * to __linux__ case error
+         */
+        msg_Err(access, "%zd bytes packet truncated (MTU was %zu)",
+                sys->mtu, len);
+#endif
     }
     else
+#endif
         pkt->i_buffer = len;
 
     return pkt;
-- 
2.19.0



More information about the vlc-devel mailing list