if (eaten) { if (tcp_in_quickack_mode(tp)) { tcp_send_ack(sk); } else { tcp_send_delayed_ack(sk); } } else { __tcp_ack_snd_check(sk, 0); }  
__tcp_ack_snd_check(sk, 0); 
int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,			struct tcphdr *th, unsigned len){	struct tcp_sock *tp = tcp_sk(sk);	/*	 *	Header prediction.	 *	The code loosely follows the one in the famous 	 *	"30 instruction TCP receive" Van Jacobson mail.	 *		 *	Van's trick is to deposit buffers into socket queue 	 *	on a device interrupt, to call tcp_recv function	 *	on the receive process context and checksum and copy	 *	the buffer to user space. smart...	 *	 *	Our current scheme is not silly either but we take the 	 *	extra cost of the net_bh soft interrupt processing...	 *	We do checksum and copy also but from device to kernel.	 */	tp->rx_opt.saw_tstamp = 0;	/*	pred_flags is 0xS?10 << 16 + snd_wnd	 *	if header_predition is to be made	 *	'S' will always be tp->tcp_header_len >> 2	 *	'?' will be 0 for the fast path, otherwise pred_flags is 0 to	 *  turn it off	(when there are holes in the receive 	 *	 space for instance)	 *	PSH flag is ignored.	 */	if ((tcp_flag_word(th) & TCP_HP_BITS) == tp->pred_flags &&		TCP_SKB_CB(skb)->seq == tp->rcv_nxt) {		int tcp_header_len = tp->tcp_header_len;		/* Timestamp header prediction: tcp_header_len		 * is automatically equal to th->doff*4 due to pred_flags		 * match.		 */		/* Check timestamp */		if (tcp_header_len == sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED) {			__u32 *ptr = (__u32 *)(th + 1);			/* No? Slow path! */			if (*ptr != ntohl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)					  | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP))				goto slow_path;			tp->rx_opt.saw_tstamp = 1;			++ptr; 			tp->rx_opt.rcv_tsval = ntohl(*ptr);			++ptr;			tp->rx_opt.rcv_tsecr = ntohl(*ptr);			/* If PAWS failed, check it more carefully in slow path */			if ((s32)(tp->rx_opt.rcv_tsval - tp->rx_opt.ts_recent) < 0)				goto slow_path;			/* DO NOT update ts_recent here, if checksum fails			 * and timestamp was corrupted part, it will result			 * in a hung connection since we will drop all			 * future packets due to the PAWS test.			 */		}		if (len <= tcp_header_len) {			/* Bulk data transfer: sender */			if (len == tcp_header_len) {				/* Predicted packet is in window by definition.				 * seq == rcv_nxt and rcv_wup <= rcv_nxt.				 * Hence, check seq<=rcv_wup reduces to:				 */				if (tcp_header_len ==				    (sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED) &&				    tp->rcv_nxt == tp->rcv_wup)					tcp_store_ts_recent(tp);				tcp_rcv_rtt_measure_ts(tp, skb);				/* We know that such packets are checksummed				 * on entry.				 */				tcp_ack(sk, skb, 0);				__kfree_skb(skb); 				tcp_data_snd_check(sk);				return 0;			} else { /* Header too small */				TCP_INC_STATS_BH(TCP_MIB_INERRS);				goto discard;			}		} else {			int eaten = 0;			if (tp->ucopy.task == current &&			    tp->copied_seq == tp->rcv_nxt &&			    len - tcp_header_len <= tp->ucopy.len &&			    sock_owned_by_user(sk)) {				__set_current_state(TASK_RUNNING);				if (!tcp_copy_to_iovec(sk, skb, tcp_header_len)) {					/* Predicted packet is in window by definition.					 * seq == rcv_nxt and rcv_wup <= rcv_nxt.					 * Hence, check seq<=rcv_wup reduces to:					 */					if (tcp_header_len ==					    (sizeof(struct tcphdr) +					     TCPOLEN_TSTAMP_ALIGNED) &&					    tp->rcv_nxt == tp->rcv_wup)						tcp_store_ts_recent(tp);					tcp_rcv_rtt_measure_ts(tp, skb);					__skb_pull(skb, tcp_header_len);					tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;					NET_INC_STATS_BH(LINUX_MIB_TCPHPHITSTOUSER);					eaten = 1;				}			}			if (!eaten) {				if (tcp_checksum_complete_user(sk, skb))					goto csum_error;				/* Predicted packet is in window by definition.				 * seq == rcv_nxt and rcv_wup <= rcv_nxt.				 * Hence, check seq<=rcv_wup reduces to:				 */				if (tcp_header_len ==				    (sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED) &&				    tp->rcv_nxt == tp->rcv_wup)					tcp_store_ts_recent(tp);				tcp_rcv_rtt_measure_ts(tp, skb);				if ((int)skb->truesize > sk->sk_forward_alloc)					goto step5;				NET_INC_STATS_BH(LINUX_MIB_TCPHPHITS);				/* Bulk data transfer: receiver */				__skb_pull(skb,tcp_header_len);				__skb_queue_tail(&sk->sk_receive_queue, skb);				sk_stream_set_owner_r(skb, sk);				tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;			}			tcp_event_data_recv(sk, tp, skb);			if (TCP_SKB_CB(skb)->ack_seq != tp->snd_una) {				/* Well, only one small jumplet in fast path... */				tcp_ack(sk, skb, FLAG_DATA);				tcp_data_snd_check(sk);				if (!tcp_ack_scheduled(tp))					goto no_ack;			}			if (eaten) {				if (tcp_in_quickack_mode(tp)) {					tcp_send_ack(sk);				} else {					tcp_send_delayed_ack(sk);				}			} else {				__tcp_ack_snd_check(sk, 0);			}no_ack:			if (eaten)				__kfree_skb(skb);			else				sk->sk_data_ready(sk, 0);			return 0;		}	}slow_path:	if (len < (th->doff<<2) || tcp_checksum_complete_user(sk, skb))		goto csum_error;	/*	 * RFC1323: H1. Apply PAWS check first.	 */	if (tcp_fast_parse_options(skb, th, tp) && tp->rx_opt.saw_tstamp &&	    tcp_paws_discard(tp, skb)) {		if (!th->rst) {			NET_INC_STATS_BH(LINUX_MIB_PAWSESTABREJECTED);			tcp_send_dupack(sk, skb);			goto discard;		}		/* Resets are accepted even if PAWS failed.		   ts_recent update must be made after we are sure		   that the packet is in window.		 */	}	/*	 *	Standard slow path.	 */	if (!tcp_sequence(tp, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq)) {		/* RFC793, page 37: "In all states except SYN-SENT, all reset		 * (RST) segments are validated by checking their SEQ-fields."		 * And page 69: "If an incoming segment is not acceptable,		 * an acknowledgment should be sent in reply (unless the RST bit		 * is set, if so drop the segment and return)".		 */		if (!th->rst)			tcp_send_dupack(sk, skb);		goto discard;	}	if(th->rst) {		tcp_reset(sk);		goto discard;	}	tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);	if (th->syn && !before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) {		TCP_INC_STATS_BH(TCP_MIB_INERRS);		NET_INC_STATS_BH(LINUX_MIB_TCPABORTONSYN);		tcp_reset(sk);		return 1;	}step5:	if(th->ack)		tcp_ack(sk, skb, FLAG_SLOWPATH);	tcp_rcv_rtt_measure_ts(tp, skb);	/* Process urgent data. */	tcp_urg(sk, skb, th);	/* step 7: process the segment text */	tcp_data_queue(sk, skb);	tcp_data_snd_check(sk);	tcp_ack_snd_check(sk);	return 0;csum_error:	TCP_INC_STATS_BH(TCP_MIB_INERRS);discard:	__kfree_skb(skb);	return 0;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/314324121f9b94b2ca657a494cf2b9cb0e4a28cc/tcp_input.c/buggy/net/ipv4/tcp_input.c