[vlc-devel] [PATCH] use overflow block on recvmsg() to adjust mtu (was: Re: [PATCH] derive truncated packet size in..)
Ilkka Ollakka
ileoo at videolan.org
Wed Oct 31 15:54:21 CET 2018
On Mon, Oct 29, 2018 at 01:11:49PM -0700, Nick Briggs wrote:
Hi,
> > On Oct 29, 2018, at 4:00 AM, vlc-devel-request at videolan.org wrote:
> > That sounds actually good idea.
> > Actually, why not just use that overflow_block and reallocate new one
> > for next overflow case, that way you wouldn't need to truncate the data.
> > Also you could use same approach in linux case and don't care about
> > MSG_TRUNC flag, but just check if received data did go to overflow_block
> > area and adjust mtu accordingly.
> We can also reduce the memory usage a little knowing that the
> maximum amount of user data in a UDP packet is 65507 bytes (a little less for IPv6)
> so the sum of regular and overflow block sizes doesn't need to exceed that.
> And here's your patch reworked with my memory reduction suggestion:
I think then approach is good. Not sure if Remi or Francois have any
opinion with this?
> From: Nick Briggs <nicholas.h.briggs at gmail.com>
> Subject: [PATCH] use overflow block on recvmsg() to adjust mtu
> Add second block on recvmsg() to check if we need to adjust mtu to be
> higher. With this approach, we will do extra memcpy and allocation in
> codepaths where mtu should be increased, but not on normal codepath.
> Allocates the minimum sized overflow block to capture the maximum
> sized datagram when combined with the normal (mtu sized) block.
> This uses the same approach on all platforms and doesn't rely on
> MSG_TRUNC in linux case and something else in other cases.
> ---
> modules/access/udp.c | 50 ++++++++++++++++++++++++++++++++++----------------
> 1 file changed, 34 insertions(+), 16 deletions(-)
> diff --git a/modules/access/udp.c b/modules/access/udp.c
> index 654ecf8..a947bb2 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,15 @@ static int Open( vlc_object_t *p_this )
> if( unlikely( sys == NULL ) )
> return VLC_ENOMEM;
> + sys->mtu = 7 * 188;
> +
> + /* Overflow can be max theoretical datagram content less anticipated MTU,
> + * IPv6 headers are larger than IPv4, ignore IPv6 jumbograms
> + */
> + sys->overflow_block = block_Alloc(65507 - sys->mtu);
> + if( unlikely( sys->overflow_block == NULL ) )
> + return VLC_ENOMEM;
> +
> p_access->p_sys = sys;
> /* Set up p_access */
> @@ -168,8 +178,6 @@ static int Open( vlc_object_t *p_this )
> return VLC_EGENERIC;
> }
> - sys->mtu = 7 * 188;
> -
> sys->timeout = var_InheritInteger( p_access, "udp-timeout");
> if( sys->timeout > 0)
> sys->timeout *= 1000;
> @@ -184,6 +192,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 );
> }
> @@ -231,20 +241,17 @@ 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 = {
> + struct iovec iov[] = {{
> .iov_base = pkt->p_buffer,
> .iov_len = sys->mtu,
> - };
> + },{
> + .iov_base = sys->overflow_block->p_buffer,
> + .iov_len = sys->overflow_block->i_buffer,
> + }};
> struct msghdr msg = {
> - .msg_iov = &iov,
> - .msg_iovlen = 1,
> - .msg_flags = trunc_flag,
> + .msg_iov = iov,
> + .msg_iovlen = 2,
> };
> struct pollfd ufd[1];
> @@ -262,7 +269,7 @@ static block_t *BlockUDP(stream_t *access, bool *restrict eof)
> goto skip;
> }
> - ssize_t len = recvmsg(sys->fd, &msg, trunc_flag);
> + ssize_t len = recvmsg(sys->fd, &msg, 0);
> if (len < 0)
> {
> @@ -271,11 +278,22 @@ skip:
> return NULL;
> }
> - if (msg.msg_flags & trunc_flag)
> + /* Received more than mtu amount,
> + * we should gather blocks and increase mtu
> + * and allocate new overflow block. See Open()
> + */
> + if (unlikely(len > sys->mtu))
> {
> - msg_Err(access, "%zd bytes packet truncated (MTU was %zu)",
> + msg_Warn(access, "%zd bytes packet received (MTU was %zu), adjusting mtu",
> len, sys->mtu);
> - pkt->i_flags |= BLOCK_FLAG_CORRUPTED;
> + block_t *gather_block = sys->overflow_block;
> +
> + sys->overflow_block = block_Alloc(65507 - len);
> +
> + gather_block->i_buffer = len - sys->mtu;
> + pkt->p_next = gather_block;
> + pkt = block_ChainGather( pkt );
> +
> sys->mtu = len;
> }
> else
--
Ilkka Ollakka
When the candles are out all women are fair.
-- Plutarch
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: Digital signature
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20181031/4baa1dd7/attachment.sig>
More information about the vlc-devel
mailing list