* copying overhead: frgagmentation, tunneling, mangling etc.
* copying overhead: fragmentation, tunneling, mangling etc.
int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb){	struct tcp_sock *tp = tcp_sk(sk); 	unsigned int cur_mss = tcp_current_mss(sk, 0);	int err;	/* Do not sent more than we queued. 1/4 is reserved for possible	 * copying overhead: frgagmentation, tunneling, mangling etc.	 */	if (atomic_read(&sk->sk_wmem_alloc) >	    min(sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2), sk->sk_sndbuf))		return -EAGAIN;	if (before(TCP_SKB_CB(skb)->seq, tp->snd_una)) {		if (before(TCP_SKB_CB(skb)->end_seq, tp->snd_una))			BUG();		if (tcp_trim_head(sk, skb, tp->snd_una - TCP_SKB_CB(skb)->seq))			return -ENOMEM;	}	/* If receiver has shrunk his window, and skb is out of	 * new window, do not retransmit it. The exception is the	 * case, when window is shrunk to zero. In this case	 * our retransmit serves as a zero window probe.	 */	if (!before(TCP_SKB_CB(skb)->seq, tp->snd_una+tp->snd_wnd)	    && TCP_SKB_CB(skb)->seq != tp->snd_una)		return -EAGAIN;	if (skb->len > cur_mss) {		if (tcp_fragment(sk, skb, cur_mss, cur_mss))			return -ENOMEM; /* We'll try again later. */	}	/* Collapse two adjacent packets if worthwhile and we can. */	if(!(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_SYN) &&	   (skb->len < (cur_mss >> 1)) &&	   (skb->next != sk->sk_send_head) &&	   (skb->next != (struct sk_buff *)&sk->sk_write_queue) &&	   (skb_shinfo(skb)->nr_frags == 0 && skb_shinfo(skb->next)->nr_frags == 0) &&	   (tcp_skb_pcount(skb) == 1 && tcp_skb_pcount(skb->next) == 1) &&	   (sysctl_tcp_retrans_collapse != 0))		tcp_retrans_try_collapse(sk, skb, cur_mss);	if(tp->af_specific->rebuild_header(sk))		return -EHOSTUNREACH; /* Routing failure or similar. */	/* Some Solaris stacks overoptimize and ignore the FIN on a	 * retransmit when old data is attached.  So strip it off	 * since it is cheap to do so and saves bytes on the network.	 */	if(skb->len > 0 &&	   (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) &&	   tp->snd_una == (TCP_SKB_CB(skb)->end_seq - 1)) {		if (!pskb_trim(skb, 0)) {			TCP_SKB_CB(skb)->seq = TCP_SKB_CB(skb)->end_seq - 1;			skb_shinfo(skb)->tso_segs = 1;			skb_shinfo(skb)->tso_size = 0;			skb->ip_summed = CHECKSUM_NONE;			skb->csum = 0;		}	}	/* Make a copy, if the first transmission SKB clone we made	 * is still in somebody's hands, else make a clone.	 */	TCP_SKB_CB(skb)->when = tcp_time_stamp;	err = tcp_transmit_skb(sk, (skb_cloned(skb) ?				    pskb_copy(skb, GFP_ATOMIC):				    skb_clone(skb, GFP_ATOMIC)));	if (err == 0) {		/* Update global TCP statistics. */		TCP_INC_STATS(TCP_MIB_RETRANSSEGS);		tp->total_retrans++;#if FASTRETRANS_DEBUG > 0		if (TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_RETRANS) {			if (net_ratelimit())				printk(KERN_DEBUG "retrans_out leaked.\n");		}#endif		TCP_SKB_CB(skb)->sacked |= TCPCB_RETRANS;		tp->retrans_out += tcp_skb_pcount(skb);		/* Save stamp of the first retransmit. */		if (!tp->retrans_stamp)			tp->retrans_stamp = TCP_SKB_CB(skb)->when;		tp->undo_retrans++;		/* snd_nxt is stored to detect loss of retransmitted segment,		 * see tcp_input.c tcp_sacktag_write_queue().		 */		TCP_SKB_CB(skb)->ack_seq = tp->snd_nxt;	}	return err;}