diff options
author | 2011-01-07 17:50:42 +0000 | |
---|---|---|
committer | 2011-01-07 17:50:42 +0000 | |
commit | 3e816f04bbb5bf8411c3134b7593ef330bd6c5c2 (patch) | |
tree | 051f70b2a5c520ad8072475c56a1d666bb18eb0c /sys/netinet/tcp_input.c | |
parent | - Update Test::Simple to 0.96 (diff) | |
download | wireguard-openbsd-3e816f04bbb5bf8411c3134b7593ef330bd6c5c2.tar.xz wireguard-openbsd-3e816f04bbb5bf8411c3134b7593ef330bd6c5c2.zip |
Add socket option SO_SPLICE to splice together two TCP sockets.
The data received on the source socket will automatically be sent
on the drain socket. This allows to write relay daemons with zero
data copy.
ok markus@
Diffstat (limited to 'sys/netinet/tcp_input.c')
-rw-r--r-- | sys/netinet/tcp_input.c | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 66ad114f222..9a6f406456f 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_input.c,v 1.239 2010/09/29 19:42:11 claudio Exp $ */ +/* $OpenBSD: tcp_input.c,v 1.240 2011/01/07 17:50:42 bluhm Exp $ */ /* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */ /* @@ -328,7 +328,9 @@ present: pool_put(&tcpqe_pool, q); q = nq; } while (q != NULL && q->tcpqe_tcp->th_seq == tp->rcv_nxt); + tp->t_flags |= TF_BLOCKOUTPUT; sorwakeup(so); + tp->t_flags &= ~TF_BLOCKOUTPUT; return (flags); } @@ -368,7 +370,7 @@ tcp_input(struct mbuf *m, ...) struct tcpcb *tp = 0; int tiflags; struct socket *so = NULL; - int todrop, acked, ourfinisacked, needoutput = 0; + int todrop, acked, ourfinisacked; int hdroptlen = 0; short ostate = 0; tcp_seq iss, *reuse = NULL; @@ -1090,9 +1092,13 @@ after_listen: TCP_TIMER_ARM(tp, TCPT_REXMT, tp->t_rxtcur); tcp_update_sndspace(tp); - if (sb_notify(&so->so_snd)) + if (sb_notify(&so->so_snd)) { + tp->t_flags |= TF_BLOCKOUTPUT; sowwakeup(so); - if (so->so_snd.sb_cc) + tp->t_flags &= ~TF_BLOCKOUTPUT; + } + if (so->so_snd.sb_cc || + tp->t_flags & TF_NEEDOUTPUT) (void) tcp_output(tp); return; } @@ -1136,8 +1142,10 @@ after_listen: m_adj(m, iphlen + off); sbappendstream(&so->so_rcv, m); } + tp->t_flags |= TF_BLOCKOUTPUT; sorwakeup(so); - if (tp->t_flags & TF_ACKNOW) + tp->t_flags &= ~TF_BLOCKOUTPUT; + if (tp->t_flags & (TF_ACKNOW|TF_NEEDOUTPUT)) (void) tcp_output(tp); return; } @@ -1773,10 +1781,10 @@ trimthenstep6: #if defined(TCP_SACK) && defined(TCP_FACK) /* Force call to tcp_output */ if (tp->snd_awnd < tp->snd_cwnd) - needoutput = 1; + tp->t_flags |= TF_NEEDOUTPUT; #else tp->snd_cwnd += tp->t_maxseg; - needoutput = 1; + tp->t_flags |= TF_NEEDOUTPUT; #endif /* TCP_FACK */ } else { /* Out of fast recovery */ @@ -1844,7 +1852,7 @@ trimthenstep6: */ if (th->th_ack == tp->snd_max) { TCP_TIMER_DISARM(tp, TCPT_REXMT); - needoutput = 1; + tp->t_flags |= TF_NEEDOUTPUT; } else if (TCP_TIMER_ISARMED(tp, TCPT_PERSIST) == 0) TCP_TIMER_ARM(tp, TCPT_REXMT, tp->t_rxtcur); /* @@ -1877,8 +1885,11 @@ trimthenstep6: } tcp_update_sndspace(tp); - if (sb_notify(&so->so_snd)) + if (sb_notify(&so->so_snd)) { + tp->t_flags |= TF_BLOCKOUTPUT; sowwakeup(so); + tp->t_flags &= ~TF_BLOCKOUTPUT; + } /* * If we had a pending ICMP message that referred to data @@ -1996,7 +2007,7 @@ step6: tp->snd_wl2 = th->th_ack; if (tp->snd_wnd > tp->max_sndwnd) tp->max_sndwnd = tp->snd_wnd; - needoutput = 1; + tp->t_flags |= TF_NEEDOUTPUT; } /* @@ -2088,7 +2099,9 @@ dodata: /* XXX */ m_adj(m, hdroptlen); sbappendstream(&so->so_rcv, m); } + tp->t_flags |= TF_BLOCKOUTPUT; sorwakeup(so); + tp->t_flags &= ~TF_BLOCKOUTPUT; } else { m_adj(m, hdroptlen); tiflags = tcp_reass(tp, th, m, &tlen); @@ -2182,9 +2195,8 @@ dodata: /* XXX */ /* * Return any desired output. */ - if (needoutput || (tp->t_flags & TF_ACKNOW)) { + if (tp->t_flags & (TF_ACKNOW|TF_NEEDOUTPUT)) (void) tcp_output(tp); - } return; badsyn: |