Page MenuHomeFreeBSD

D12492.id33406.diff
No OneTemporary

D12492.id33406.diff

Index: sys/kern/kern_sendfile.c
===================================================================
--- sys/kern/kern_sendfile.c
+++ sys/kern/kern_sendfile.c
@@ -866,9 +866,16 @@
CURVNET_RESTORE();
m = NULL; /* pru_send always consumes */
+ /* if pru_send errored, then it didn't add data to the socket */
if (error)
goto done;
sbytes += space + hdrlen;
+ /* pru_send stores errors after adding data to the socket here */
+ if (so->so_error) {
+ error = so->so_error;
+ so->so_error = 0;
+ goto done;
+ }
if (hdrlen)
hdrlen = 0;
if (softerr) {
Index: sys/netinet/tcp_usrreq.c
===================================================================
--- sys/netinet/tcp_usrreq.c
+++ sys/netinet/tcp_usrreq.c
@@ -877,13 +877,19 @@
* marker if URG set. Possibly send more data. Unlike the other
* pru_*() routines, the mbuf chains are our responsibility. We
* must either enqueue them or free them. The other pru_* routines
- * generally are caller-frees.
+ * generally are caller-frees. We must either add the mbuf chain
+ * to the socket send buffer or return an error, not both. We
+ * ensure that after adding the mbufs to the send buffer, we will
+ * not return any more errors. Errors from tcp_output are not
+ * passed back to the caller, but are instead deposited in
+ * so->so_error for the next call.
*/
static int
tcp_usr_send(struct socket *so, int flags, struct mbuf *m,
struct sockaddr *nam, struct mbuf *control, struct thread *td)
{
int error = 0;
+ int so_error = 0;
struct inpcb *inp;
struct tcpcb *tp = NULL;
#ifdef INET6
@@ -929,7 +935,6 @@
m_freem(control); /* empty control, just free it */
}
if (!(flags & PRUS_OOB)) {
- sbappendstream(&so->so_snd, m, flags);
if (nam && tp->t_state < TCPS_SYN_SENT) {
/*
* Do implied connect if not yet connected,
@@ -951,6 +956,7 @@
tp->snd_wnd = TTCP_CLIENT_SND_WND;
tcp_mss(tp, -1);
}
+ sbappendstream(&so->so_snd, m, flags);
if (flags & PRUS_EOF) {
/*
* Close the send side of the connection after
@@ -964,7 +970,10 @@
!(flags & PRUS_NOTREADY)) {
if (flags & PRUS_MORETOCOME)
tp->t_flags |= TF_MORETOCOME;
- error = tp->t_fb->tfb_tcp_output(tp);
+ so_error = tp->t_fb->tfb_tcp_output(tp);
+ /* next socket syscall call will return this error */
+ if (so_error && !so->so_error)
+ so->so_error = so_error;
if (flags & PRUS_MORETOCOME)
tp->t_flags &= ~TF_MORETOCOME;
}
@@ -972,23 +981,6 @@
/*
* XXXRW: PRUS_EOF not implemented with PRUS_OOB?
*/
- SOCKBUF_LOCK(&so->so_snd);
- if (sbspace(&so->so_snd) < -512) {
- SOCKBUF_UNLOCK(&so->so_snd);
- m_freem(m);
- error = ENOBUFS;
- goto out;
- }
- /*
- * According to RFC961 (Assigned Protocols),
- * the urgent pointer points to the last octet
- * of urgent data. We continue, however,
- * to consider it to indicate the first octet
- * of data past the urgent section.
- * Otherwise, snd_up should be one lower.
- */
- sbappendstream_locked(&so->so_snd, m, flags);
- SOCKBUF_UNLOCK(&so->so_snd);
if (nam && tp->t_state < TCPS_SYN_SENT) {
/*
* Do implied connect if not yet connected,
@@ -1010,10 +1002,30 @@
tp->snd_wnd = TTCP_CLIENT_SND_WND;
tcp_mss(tp, -1);
}
+ SOCKBUF_LOCK(&so->so_snd);
+ if (sbspace(&so->so_snd) < -512) {
+ SOCKBUF_UNLOCK(&so->so_snd);
+ m_freem(m);
+ error = ENOBUFS;
+ goto out;
+ }
+ /*
+ * According to RFC961 (Assigned Protocols),
+ * the urgent pointer points to the last octet
+ * of urgent data. We continue, however,
+ * to consider it to indicate the first octet
+ * of data past the urgent section.
+ * Otherwise, snd_up should be one lower.
+ */
+ sbappendstream_locked(&so->so_snd, m, flags);
tp->snd_up = tp->snd_una + sbavail(&so->so_snd);
+ SOCKBUF_UNLOCK(&so->so_snd);
if (!(flags & PRUS_NOTREADY)) {
tp->t_flags |= TF_FORCEDATA;
- error = tp->t_fb->tfb_tcp_output(tp);
+ so_error = tp->t_fb->tfb_tcp_output(tp);
+ /* next socket syscall call will return this error */
+ if (so_error && !so->so_error)
+ so->so_error = so_error;
tp->t_flags &= ~TF_FORCEDATA;
}
}

File Metadata

Mime Type
text/plain
Expires
Wed, Sep 2, 4:13 AM (5 h, 33 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37674797
Default Alt Text
D12492.id33406.diff (4 KB)

Event Timeline