Merge from projects/sendfile:

- Provide pru_ready function for TCP.
- Don't call tcp_output() from tcp_usr_send() if no ready data was put
  into the socket buffer.
- In case of dropped connection don't try to m_freem() not ready data.

Sponsored by:	Nginx, Inc.
Sponsored by:	Netflix
This commit is contained in:
Gleb Smirnoff 2014-11-30 13:43:52 +00:00
parent c80ea19b38
commit 2cbcd3c198

View File

@ -821,7 +821,11 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m,
if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
if (control)
m_freem(control);
if (m)
/*
* In case of PRUS_NOTREADY, tcp_usr_ready() is responsible
* for freeing memory.
*/
if (m && (flags & PRUS_NOTREADY) == 0)
m_freem(m);
error = ECONNRESET;
goto out;
@ -875,7 +879,8 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m,
socantsendmore(so);
tcp_usrclosed(tp);
}
if (!(inp->inp_flags & INP_DROPPED)) {
if (!(inp->inp_flags & INP_DROPPED) &&
!(flags & PRUS_NOTREADY)) {
if (flags & PRUS_MORETOCOME)
tp->t_flags |= TF_MORETOCOME;
error = tcp_output(tp);
@ -926,9 +931,11 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m,
tcp_mss(tp, -1);
}
tp->snd_up = tp->snd_una + sbavail(&so->so_snd);
tp->t_flags |= TF_FORCEDATA;
error = tcp_output(tp);
tp->t_flags &= ~TF_FORCEDATA;
if (!(flags & PRUS_NOTREADY)) {
tp->t_flags |= TF_FORCEDATA;
error = tcp_output(tp);
tp->t_flags &= ~TF_FORCEDATA;
}
}
out:
TCPDEBUG2((flags & PRUS_OOB) ? PRU_SENDOOB :
@ -939,6 +946,33 @@ out:
return (error);
}
static int
tcp_usr_ready(struct socket *so, struct mbuf *m, int count)
{
struct inpcb *inp;
struct tcpcb *tp;
int error;
inp = sotoinpcb(so);
INP_WLOCK(inp);
if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
INP_WUNLOCK(inp);
for (int i = 0; i < count; i++)
m = m_free(m);
return (ECONNRESET);
}
tp = intotcpcb(inp);
SOCKBUF_LOCK(&so->so_snd);
error = sbready(&so->so_snd, m, count);
SOCKBUF_UNLOCK(&so->so_snd);
if (error == 0)
error = tcp_output(tp);
INP_WUNLOCK(inp);
return (error);
}
/*
* Abort the TCP. Drop the connection abruptly.
*/
@ -1073,6 +1107,7 @@ struct pr_usrreqs tcp_usrreqs = {
.pru_rcvd = tcp_usr_rcvd,
.pru_rcvoob = tcp_usr_rcvoob,
.pru_send = tcp_usr_send,
.pru_ready = tcp_usr_ready,
.pru_shutdown = tcp_usr_shutdown,
.pru_sockaddr = in_getsockaddr,
.pru_sosetlabel = in_pcbsosetlabel,
@ -1095,6 +1130,7 @@ struct pr_usrreqs tcp6_usrreqs = {
.pru_rcvd = tcp_usr_rcvd,
.pru_rcvoob = tcp_usr_rcvoob,
.pru_send = tcp_usr_send,
.pru_ready = tcp_usr_ready,
.pru_shutdown = tcp_usr_shutdown,
.pru_sockaddr = in6_mapped_sockaddr,
.pru_sosetlabel = in_pcbsosetlabel,