Deleted Added
full compact
tcp_output.c (87145) tcp_output.c (87193)
1/*
2 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 17 unchanged lines hidden (view full) ---

26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)tcp_output.c 8.4 (Berkeley) 5/24/95
1/*
2 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 17 unchanged lines hidden (view full) ---

26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)tcp_output.c 8.4 (Berkeley) 5/24/95
34 * $FreeBSD: head/sys/netinet/tcp_output.c 87145 2001-11-30 21:33:39Z dillon $
34 * $FreeBSD: head/sys/netinet/tcp_output.c 87193 2001-12-02 08:49:29Z dillon $
35 */
36
37#include "opt_inet6.h"
38#include "opt_ipsec.h"
39#include "opt_tcpdebug.h"
40
41#include <sys/param.h>
42#include <sys/systm.h>

--- 70 unchanged lines hidden (view full) ---

113 register struct ipovly *ipov = NULL;
114#ifdef INET6
115 struct ip6_hdr *ip6 = NULL;
116#endif /* INET6 */
117 register struct tcphdr *th;
118 u_char opt[TCP_MAXOLEN];
119 unsigned ipoptlen, optlen, hdrlen;
120 int idle, sendalot;
35 */
36
37#include "opt_inet6.h"
38#include "opt_ipsec.h"
39#include "opt_tcpdebug.h"
40
41#include <sys/param.h>
42#include <sys/systm.h>

--- 70 unchanged lines hidden (view full) ---

113 register struct ipovly *ipov = NULL;
114#ifdef INET6
115 struct ip6_hdr *ip6 = NULL;
116#endif /* INET6 */
117 register struct tcphdr *th;
118 u_char opt[TCP_MAXOLEN];
119 unsigned ipoptlen, optlen, hdrlen;
120 int idle, sendalot;
121#if 0
121 int maxburst = TCP_MAXBURST;
122 int maxburst = TCP_MAXBURST;
123#endif
122 struct rmxp_tao *taop;
123 struct rmxp_tao tao_noncached;
124#ifdef INET6
125 int isipv6;
126#endif
127
128#ifdef INET6
129 isipv6 = (tp->t_inpcb->inp_vflag & INP_IPV6) != 0;

--- 142 unchanged lines hidden (view full) ---

272 sendalot = 1;
273 }
274 if (SEQ_LT(tp->snd_nxt + len, tp->snd_una + so->so_snd.sb_cc))
275 flags &= ~TH_FIN;
276
277 win = sbspace(&so->so_rcv);
278
279 /*
124 struct rmxp_tao *taop;
125 struct rmxp_tao tao_noncached;
126#ifdef INET6
127 int isipv6;
128#endif
129
130#ifdef INET6
131 isipv6 = (tp->t_inpcb->inp_vflag & INP_IPV6) != 0;

--- 142 unchanged lines hidden (view full) ---

274 sendalot = 1;
275 }
276 if (SEQ_LT(tp->snd_nxt + len, tp->snd_una + so->so_snd.sb_cc))
277 flags &= ~TH_FIN;
278
279 win = sbspace(&so->so_rcv);
280
281 /*
280 * Sender silly window avoidance. If connection is idle
281 * and can send all data, a maximum segment,
282 * at least a maximum default-size segment do it,
283 * or are forced, do it; otherwise don't bother.
284 * If peer's buffer is tiny, then send
285 * when window is at least half open.
286 * If retransmitting (possibly after persist timer forced us
287 * to send into a small window), then must resend.
282 * Sender silly window avoidance. We transmit under the following
283 * conditions when len is non-zero:
284 *
285 * - We have a full segment
286 * - This is the last buffer in a write()/send() and we are
287 * either idle or running NODELAY
288 * - we've timed out (e.g. persist timer)
289 * - we have more then 1/2 the maximum send window's worth of
290 * data (receiver may be limited the window size)
291 * - we need to retransmit
288 */
289 if (len) {
290 if (len == tp->t_maxseg)
291 goto send;
292 */
293 if (len) {
294 if (len == tp->t_maxseg)
295 goto send;
292 if (!(tp->t_flags & TF_MORETOCOME) &&
293 (idle || tp->t_flags & TF_NODELAY) &&
294 (tp->t_flags & TF_NOPUSH) == 0 &&
295 len + off >= so->so_snd.sb_cc)
296 /*
297 * NOTE! on localhost connections an 'ack' from the remote
298 * end may occur synchronously with the output and cause
299 * us to flush a buffer queued with moretocome. XXX
300 *
301 * note: the len + off check is almost certainly unnecessary.
302 */
303 if (!(tp->t_flags & TF_MORETOCOME) && /* normal case */
304 (idle || (tp->t_flags & TF_NODELAY)) &&
305 len + off >= so->so_snd.sb_cc &&
306 (tp->t_flags & TF_NOPUSH) == 0) {
296 goto send;
307 goto send;
297 if (tp->t_force)
308 }
309 if (tp->t_force) /* typ. timeout case */
298 goto send;
299 if (len >= tp->max_sndwnd / 2 && tp->max_sndwnd > 0)
300 goto send;
310 goto send;
311 if (len >= tp->max_sndwnd / 2 && tp->max_sndwnd > 0)
312 goto send;
301 if (SEQ_LT(tp->snd_nxt, tp->snd_max))
313 if (SEQ_LT(tp->snd_nxt, tp->snd_max)) /* retransmit case */
302 goto send;
303 }
304
305 /*
306 * Compare available window to amount of window
307 * known to peer (as advertised window less
308 * next expected input). If the difference is at least two
309 * max size segments, or at least 50% of the maximum possible

--- 382 unchanged lines hidden (view full) ---

692 */
693 if (win < (long)(so->so_rcv.sb_hiwat / 4) && win < (long)tp->t_maxseg)
694 win = 0;
695 if (win < (long)(tp->rcv_adv - tp->rcv_nxt))
696 win = (long)(tp->rcv_adv - tp->rcv_nxt);
697 if (win > (long)TCP_MAXWIN << tp->rcv_scale)
698 win = (long)TCP_MAXWIN << tp->rcv_scale;
699 th->th_win = htons((u_short) (win>>tp->rcv_scale));
314 goto send;
315 }
316
317 /*
318 * Compare available window to amount of window
319 * known to peer (as advertised window less
320 * next expected input). If the difference is at least two
321 * max size segments, or at least 50% of the maximum possible

--- 382 unchanged lines hidden (view full) ---

704 */
705 if (win < (long)(so->so_rcv.sb_hiwat / 4) && win < (long)tp->t_maxseg)
706 win = 0;
707 if (win < (long)(tp->rcv_adv - tp->rcv_nxt))
708 win = (long)(tp->rcv_adv - tp->rcv_nxt);
709 if (win > (long)TCP_MAXWIN << tp->rcv_scale)
710 win = (long)TCP_MAXWIN << tp->rcv_scale;
711 th->th_win = htons((u_short) (win>>tp->rcv_scale));
712
713
714 /*
715 * Adjust the RXWIN0SENT flag - indicate that we have advertised
716 * a 0 window. This may cause the remote transmitter to stall. This
717 * flag tells soreceive() to disable delayed acknowledgements when
718 * draining the buffer. This can occur if the receiver is attempting
719 * to read more data then can be buffered prior to transmitting on
720 * the connection.
721 */
722 if (win == 0)
723 tp->t_flags |= TF_RXWIN0SENT;
724 else
725 tp->t_flags &= ~TF_RXWIN0SENT;
700 if (SEQ_GT(tp->snd_up, tp->snd_nxt)) {
701 th->th_urp = htons((u_short)(tp->snd_up - tp->snd_nxt));
702 th->th_flags |= TH_URG;
703 } else
704 /*
705 * If no urgent pointer to send, then we pull
706 * the urgent pointer to the left edge of the send window
707 * so that it doesn't drift into the send window on sequence

--- 249 unchanged lines hidden ---
726 if (SEQ_GT(tp->snd_up, tp->snd_nxt)) {
727 th->th_urp = htons((u_short)(tp->snd_up - tp->snd_nxt));
728 th->th_flags |= TH_URG;
729 } else
730 /*
731 * If no urgent pointer to send, then we pull
732 * the urgent pointer to the left edge of the send window
733 * so that it doesn't drift into the send window on sequence

--- 249 unchanged lines hidden ---