]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/ipv4/tcp_output.c
tcp: don't backtrack to sacked skbs
[linux-2.6-omap-h63xx.git] / net / ipv4 / tcp_output.c
index dda42f0bd7a3b986d23be16b6f44c87333af0844..2471cd4f66db7f99a1855e7837f94b9cb4a3ed3c 100644 (file)
@@ -663,10 +663,14 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
        th->urg_ptr             = 0;
 
        /* The urg_mode check is necessary during a below snd_una win probe */
-       if (unlikely(tcp_urg_mode(tp) &&
-                    between(tp->snd_up, tcb->seq + 1, tcb->seq + 0xFFFF))) {
-               th->urg_ptr             = htons(tp->snd_up - tcb->seq);
-               th->urg                 = 1;
+       if (unlikely(tcp_urg_mode(tp) && before(tcb->seq, tp->snd_up))) {
+               if (before(tp->snd_up, tcb->seq + 0x10000)) {
+                       th->urg_ptr = htons(tp->snd_up - tcb->seq);
+                       th->urg = 1;
+               } else if (after(tcb->seq + 0xFFFF, tp->snd_nxt)) {
+                       th->urg_ptr = 0xFFFF;
+                       th->urg = 1;
+               }
        }
 
        tcp_options_write((__be32 *)(th + 1), tp, &opts, &md5_hash_location);
@@ -2023,7 +2027,6 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
                last_lost = tp->snd_una;
        }
 
-       /* First pass: retransmit lost packets. */
        tcp_for_write_queue_from(skb, sk) {
                __u8 sacked = TCP_SKB_CB(skb)->sacked;
 
@@ -2062,7 +2065,7 @@ begin_fwd:
                        goto begin_fwd;
 
                } else if (!(sacked & TCPCB_LOST)) {
-                       if (hole == NULL && !(sacked & TCPCB_SACKED_RETRANS))
+                       if (hole == NULL && !(sacked & (TCPCB_SACKED_RETRANS|TCPCB_SACKED_ACKED)))
                                hole = skb;
                        continue;