Skip to content
Snippets Groups Projects
tcp_output.c 59.6 KiB
Newer Older
  • Learn to ignore specific revisions
  • Linus Torvalds's avatar
    Linus Torvalds committed
    				}
    			} else if (!tcp_skb_pcount(skb))
    
    				tcp_set_skb_tso_segs(sk, skb, mss);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    
    			TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH;
    			TCP_SKB_CB(skb)->when = tcp_time_stamp;
    			err = tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC));
    			if (!err) {
    				update_send_head(sk, tp, skb);
    			}
    			return err;
    		} else {
    			if (tp->urg_mode &&
    			    between(tp->snd_up, tp->snd_una+1, tp->snd_una+0xFFFF))
    				tcp_xmit_probe_skb(sk, TCPCB_URG);
    			return tcp_xmit_probe_skb(sk, 0);
    		}
    	}
    	return -1;
    }
    
    /* A window probe timeout has occurred.  If window is not closed send
     * a partial packet else a zero probe.
     */
    void tcp_send_probe0(struct sock *sk)
    {
    
    	struct inet_connection_sock *icsk = inet_csk(sk);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    	struct tcp_sock *tp = tcp_sk(sk);
    	int err;
    
    	err = tcp_write_wakeup(sk);
    
    	if (tp->packets_out || !sk->sk_send_head) {
    		/* Cancel probe timer, if it is not required. */
    
    		icsk->icsk_backoff = 0;
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    		return;
    	}
    
    	if (err <= 0) {
    
    		if (icsk->icsk_backoff < sysctl_tcp_retries2)
    			icsk->icsk_backoff++;
    
    		inet_csk_reset_xmit_timer(sk, ICSK_TIME_PROBE0, 
    
    					  min(icsk->icsk_rto << icsk->icsk_backoff, TCP_RTO_MAX),
    					  TCP_RTO_MAX);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    	} else {
    		/* If packet was not sent due to local congestion,
    
    		 * do not backoff and do not remember icsk_probes_out.
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    		 * Let local senders to fight for local resources.
    		 *
    		 * Use accumulated backoff yet.
    		 */
    
    		if (!icsk->icsk_probes_out)
    			icsk->icsk_probes_out = 1;
    
    		inet_csk_reset_xmit_timer(sk, ICSK_TIME_PROBE0, 
    					  min(icsk->icsk_rto << icsk->icsk_backoff,
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    	}
    }
    
    EXPORT_SYMBOL(tcp_connect);
    EXPORT_SYMBOL(tcp_make_synack);
    EXPORT_SYMBOL(tcp_simple_retransmit);
    EXPORT_SYMBOL(tcp_sync_mss);