We have a lot of different variables at play here: song size, song
bitrate, LMS, squeezelite, squeezelite stream buffer, server TCP send
buffer, client TCP receive buffer, server TCP FIN timeout. Lets briefly
look into what each of these contribute.


Song size and song bitrate - we don't have any control over these, but
they obviously play big role in this failure. Song needs to be big
enough to fill all the buffers and bitrate needs to be low enough to
slow down how fast buffers are drained. Most of the songs do not meet
requirements to trigger this issue though.

LMS is not really doing anything wrong, it sends the data out as fast as
it can and once all of the data is written to the socket it closes it.

squeezelite is also not at fault here, it is reading data as fast as it
can and suddenly socket disappears on it. I ran this same test with
squeezeplay and failure mode was exactly the same. Squeezeplay uses
larger buffer size 3145728 (vs 2097152) so everything failed closer to
the end of the song.

TCP send buffer - the size of this buffer does not really matter,
because kernel TCP stack sends TCP FIN packet to the client only after
this buffer is emptied.

squeezelite stream buffer - this can be increased and it will reduce how
often this issue happens, but it will not eliminate the issue. You can
always find file that will be larger than the buffer size.

TCP receive buffer and TCP FIN timeout - the combination of these is
what causes the issue. If the TCP receive buffer is larger than the TCP
FIN timeout multiplied by the song bitrate, we are going to have a
failure. To test this I have increased TCP FIN timeout
(net.ipv4.tcp_fin_timeout) on the server from 60 sec to 120 sec and that
of course allowed enough time for the client to finish reading data from
the TCP buffers. Client finished reading data 84 seconds after server
finished sending data.

34910


What are some of the possible solutions? Haven't given much thought to
these, so some might not make sense.

Increasing squeezelite stream buffer - that's what most of the people
that experience this issue are doing now.

Increasing TCP FIN timeout (net.ipv4.tcp_fin_timeout) on the server - it
is a system wide setting and might not be a good idea if LMS is not
running on the dedicated box.

LMS setting FIN time out on the socket level using SO_LINGER - not sure
if this is possible though.

Squeezelite explicitly setting TCP receive buffer size on the socket
level using SO_RCVBUF - is this possible.

LMS waiting to close the socket until Squeezelite notifies it that all
of the data was received - this would be the only way to cover 100% of
the cases, but is this possible to do?


Thanks for reading and sorry for the long posts!


+-------------------------------------------------------------------+
|Filename: tcp_session_ok_large_fin_timeout.jpg                     |
|Download: http://forums.slimdevices.com/attachment.php?attachmentid=34910|
+-------------------------------------------------------------------+

------------------------------------------------------------------------
lngxa's Profile: http://forums.slimdevices.com/member.php?userid=71826
View this thread: http://forums.slimdevices.com/showthread.php?t=114661

_______________________________________________
Squeezecenter mailing list
[email protected]
http://lists.slimdevices.com/mailman/listinfo/squeezecenter

Reply via email to