]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/commit
MFC r240003, r240004:
authortrociny <trociny@ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f>
Mon, 17 Sep 2012 14:53:33 +0000 (14:53 +0000)
committertrociny <trociny@ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f>
Mon, 17 Sep 2012 14:53:33 +0000 (14:53 +0000)
commit40a165f4242348fa7039a0a999d61c0369b66747
treeff61731a6d5c17a9d4608d01fce576220f66e4de
parent84eedcff13df8104e94a805e732aa8b36faa5182
MFC r240003, r240004:

r240003:

In soreceive_generic() when checking if the type of mbuf has changed
check it for MT_CONTROL type too, otherwise the assertion
"m->m_type == MT_DATA" below may be triggered by the following scenario:

- the sender sends some data (MT_DATA) and then a file descriptor
  (MT_CONTROL);
- the receiver calls recv(2) with a MSG_WAITALL asking for data larger
  than the receive buffer (uio_resid > hiwat).

r240004:

In soreceive_generic() remove the optimization for the case when
MSG_WAITALL is set, and it is possible to do the entire receive
operation at once if we block (resid <= hiwat). Actually it might make
the recv(2) with MSG_WAITALL flag get stuck when there is enough space
in the receiver buffer to satisfy the request but not enough to open
the window closed previously due to the buffer being full.

The issue can be reproduced using the following scenario:

On the sender side do 2 send(2) requests:

1) data of size much smaller than SOBUF_SIZE (e.g. SOBUF_SIZE / 10);
2) data of size equal to SOBUF_SIZE.

On the receiver side do 2 recv(2) requests with MSG_WAITALL flag set:

1) recv() data of SOBUF_SIZE / 10 size;
2) recv() data of SOBUF_SIZE size;

We totally fill the receiver buffer with one SOBUF_SIZE/10 size request
and partial SOBUF_SIZE request. When the first request is processed we
get SOBUF_SIZE/10 free space. It is just enough to receive the rest of
bytes for the second request, and soreceive_generic() blocks in the
part that is a subject of this change waiting for the rest. But the
window was closed when the buffer was filled and to avoid silly window
syndrome it opens only when available space is larger than sb_hiwat/4
or maxseg. So it is stuck and pending data is only sent via TCP window
probes.

Discussed with: kib (long ago)

git-svn-id: svn://svn.freebsd.org/base/stable/9@240606 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
sys/kern/uipc_socket.c