[vlc-devel] [PATCH 1/2] access/udp: use MSG_PEEK for non-linux cases to check new size

Ilkka Ollakka ileoo at videolan.org
Fri Oct 26 19:26:25 CEST 2018


---
 modules/access/udp.c | 48 ++++++++++++++++++++++++++++++++++++--------
 1 file changed, 40 insertions(+), 8 deletions(-)

diff --git a/modules/access/udp.c b/modules/access/udp.c
index 654ecf83c3..ccae192587 100644
--- a/modules/access/udp.c
+++ b/modules/access/udp.c
@@ -81,6 +81,7 @@ typedef struct
     int fd;
     int timeout;
     size_t mtu;
+    block_t *peek_block;
 } access_sys_t;
 
 /*****************************************************************************
@@ -104,6 +105,15 @@ static int Open( vlc_object_t *p_this )
     if( unlikely( sys == NULL ) )
         return VLC_ENOMEM;
 
+    sys->peek_block = NULL;
+#ifdef MSG_TRUNC
+# ifndef __linux__
+    sys->peek_block = block_Alloc(65536);
+    if( unlikely( sys->peek_block == NULL ) )
+        return VLC_ENOMEM;
+# endif
+#endif
+
     p_access->p_sys = sys;
 
     /* Set up p_access */
@@ -184,6 +194,8 @@ static void Close( vlc_object_t *p_this )
 {
     stream_t     *p_access = (stream_t*)p_this;
     access_sys_t *sys = p_access->p_sys;
+    if( sys->peek_block )
+        block_Release( sys->peek_block );
 
     net_Close( sys->fd );
 }
@@ -231,11 +243,6 @@ static block_t *BlockUDP(stream_t *access, bool *restrict eof)
         return NULL;
     }
 
-#ifdef __linux__
-    const int trunc_flag = MSG_TRUNC;
-#else
-    const int trunc_flag = 0;
-#endif
 
     struct iovec iov = {
         .iov_base = pkt->p_buffer,
@@ -244,7 +251,6 @@ static block_t *BlockUDP(stream_t *access, bool *restrict eof)
     struct msghdr msg = {
         .msg_iov = &iov,
         .msg_iovlen = 1,
-        .msg_flags = trunc_flag,
     };
 
     struct pollfd ufd[1];
@@ -262,6 +268,15 @@ static block_t *BlockUDP(stream_t *access, bool *restrict eof)
             goto skip;
      }
 
+#ifdef __linux__
+    /* We define MSG_TRUNC only for linux
+     * as for other systems it's not defined flag for input
+     */
+    const int trunc_flag = MSG_TRUNC;
+#else
+    const int trunc_flag = 0;
+#endif
+
     ssize_t len = recvmsg(sys->fd, &msg, trunc_flag);
 
     if (len < 0)
@@ -271,14 +286,31 @@ skip:
         return NULL;
     }
 
-    if (msg.msg_flags & trunc_flag)
+#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 use MSG_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 and the result
+           is most likely correct mtu size if current was truncated.
+         */
+# 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
+        size_t old_mtu = sys->mtu;
+        sys->mtu = recv(sys->fd, sys->peek_block->p_buffer, sys->peek_block->i_buffer, MSG_PEEK);
+
+        msg_Err(access, "%zd bytes packet truncated (MTU was %zu)",
+                sys->mtu, old_mtu);
+# endif
     }
     else
+#endif
         pkt->i_buffer = len;
 
     return pkt;
-- 
2.19.1



More information about the vlc-devel mailing list