[vlc-devel] [PATCH 1/2] access/udp: use MSG_PEEK for non-linux cases to check new size
Nick Briggs
nicholas.h.briggs at gmail.com
Sat Oct 27 19:50:07 CEST 2018
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.
Date: Fri, 26 Oct 2018 20:26:25 +0300
> From: Ilkka Ollakka <ileoo at videolan.org>
> To: vlc-devel at videolan.org
> Subject: [vlc-devel] [PATCH 1/2] access/udp: use MSG_PEEK for
> non-linux cases to check new size
> Message-ID: <20181026172626.17043-1-ileoo at videolan.org>
>
> ---
> 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