summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2011-08-20 16:12:29 +0000
committerkib <kib@FreeBSD.org>2011-08-20 16:12:29 +0000
commit1d5badd36f3a428d1994f6bdd8d7321e70ced572 (patch)
treef84fa68bdbd8090737eb944122d6e3c86db6b7e4
parent9b44ba7fde351b9f280a957237fbe64db3f601e9 (diff)
downloadFreeBSD-src-1d5badd36f3a428d1994f6bdd8d7321e70ced572.zip
FreeBSD-src-1d5badd36f3a428d1994f6bdd8d7321e70ced572.tar.gz
Prevent the hiwatermark for the unix domain socket from becoming
effectively negative. Often seen as upstream fastcgi connection timeouts in nginx when using sendfile over unix domain sockets for communication. Sendfile(2) may send more bytes then currently allowed by the hiwatermark of the socket, e.g. because the so_snd sockbuf lock is dropped after sbspace() call in the kern_sendfile() loop. In this case, recalculated hiwatermark will overflow. Since lowatermark is renewed as half of the hiwatermark by sendfile code, and both are unsigned, the send buffer never reaches the free space requested by lowatermark, causing indefinite wait in sendfile. Reviewed by: rwatson Approved by: re (bz) MFC after: 2 weeks
-rw-r--r--sys/kern/uipc_usrreq.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index 4bad386..3a34f58 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -816,7 +816,7 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
struct unpcb *unp, *unp2;
struct socket *so2;
u_int mbcnt_delta, sbcc;
- u_long newhiwat;
+ u_int newhiwat;
int error = 0;
unp = sotounpcb(so);
@@ -974,7 +974,10 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
sorwakeup_locked(so2);
SOCKBUF_LOCK(&so->so_snd);
- newhiwat = so->so_snd.sb_hiwat - (sbcc - unp2->unp_cc);
+ if ((int)so->so_snd.sb_hiwat >= (int)(sbcc - unp2->unp_cc))
+ newhiwat = so->so_snd.sb_hiwat - (sbcc - unp2->unp_cc);
+ else
+ newhiwat = 0;
(void)chgsbsize(so->so_cred->cr_uidinfo, &so->so_snd.sb_hiwat,
newhiwat, RLIM_INFINITY);
so->so_snd.sb_mbmax -= mbcnt_delta;
OpenPOWER on IntegriCloud