Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F169306497
D12492.id33406.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D12492.id33406.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D12492: Ensure strict error handling of tcp_usr_send
Attached
Detach File
Event Timeline
Log In to Comment