[vlc-devel] [PATCH] derive truncated packet size in non-linux recvmsg case by using overflow buffer

Nick Briggs nicholas.h.briggs at gmail.com
Sun Oct 28 02:58:59 CEST 2018


> On Oct 27, 2018, at 10:50 AM, Nick Briggs <nicholas.h.briggs at gmail.com> wrote:
> 
> Here's an alternate idea to handle the non-Linux case:
> 
> Since you're allocating the peek_block, make your iov array 2 elements, add the peek buffer as the second element, and just check if the returned length is greater than the primary block you were reading into. MSG_TRUNC will never be set. It would then mirror the logic of the Linux case with the MSG_TRUNC in the recvmsg() flags, and it doesn't depend on PEEKing the *next* block to see if it is also bigger than the expected MTU. 

For example, and then it also avoids the change to the Windows compatibility code, assuming it handles scatter/gather in recvmsg() the same way.

The "len > sys->mtu" comparison generates a warning for comparison of differently signed integers (compiling with clang), but those seem to be fairly frequent in the existing code.

---
 modules/access/udp.c | 35 ++++++++++++++++++++++++++++-------
 1 file changed, 28 insertions(+), 7 deletions(-)

diff --git a/modules/access/udp.c b/modules/access/udp.c
index 654ecf8..7d94796 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 *overflow_block;
 } access_sys_t;
 
 /*****************************************************************************
@@ -104,6 +105,13 @@ static int Open( vlc_object_t *p_this )
     if( unlikely( sys == NULL ) )
         return VLC_ENOMEM;
 
+    sys->overflow_block = NULL;
+#ifndef __linux__
+    sys->overflow_block = block_Alloc(65536);
+    if( unlikely( sys->overflow_block == NULL ) )
+        return VLC_ENOMEM;
+#endif
+
     p_access->p_sys = sys;
 
     /* Set up p_access */
@@ -185,6 +193,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->overflow_block )
+        block_Release( sys->overflow_block );
     net_Close( sys->fd );
 }
 
@@ -237,14 +247,25 @@ static block_t *BlockUDP(stream_t *access, bool *restrict eof)
     const int trunc_flag = 0;
 #endif
 
-    struct iovec iov = {
-        .iov_base = pkt->p_buffer,
-        .iov_len = sys->mtu,
+    struct iovec iov[2] = {
+        {
+            .iov_base = pkt->p_buffer,
+            .iov_len = sys->mtu
+        },
+#ifndef __linux__
+        {
+            .iov_base = sys->overflow_block,
+            .iov_len = 65536		/* see block_Alloc() */
+        }
+#endif
     };
     struct msghdr msg = {
-        .msg_iov = &iov,
-        .msg_iovlen = 1,
-        .msg_flags = trunc_flag,
+        .msg_iov = &iov[0],
+#ifdef __linux__
+        .msg_iovlen = 1
+#else
+        .msg_iovlen = 2
+#endif
     };
 
     struct pollfd ufd[1];
@@ -271,7 +292,7 @@ skip:
         return NULL;
     }
 
-    if (msg.msg_flags & trunc_flag)
+    if (len > sys->mtu)
     {
         msg_Err(access, "%zd bytes packet truncated (MTU was %zu)",
                 len, sys->mtu);
-- 
2.10.1 (Apple Git-78)



More information about the vlc-devel mailing list