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:
parent
c80ea19b38
commit
2cbcd3c198
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user