tcp_ack_saw_tstamp(sk, 0, 0); 
tcp_ack_saw_tstamp(sk, NULL, 0); 
int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,			  struct tcphdr *th, unsigned len){	struct tcp_sock *tp = tcp_sk(sk);	int queued = 0;	tp->rx_opt.saw_tstamp = 0;	switch (sk->sk_state) {	case TCP_CLOSE:		goto discard;	case TCP_LISTEN:		if(th->ack)			return 1;		if(th->rst)			goto discard;		if(th->syn) {			if(tp->af_specific->conn_request(sk, skb) < 0)				return 1;			/* Now we have several options: In theory there is 			 * nothing else in the frame. KA9Q has an option to 			 * send data with the syn, BSD accepts data with the			 * syn up to the [to be] advertised window and 			 * Solaris 2.1 gives you a protocol error. For now 			 * we just ignore it, that fits the spec precisely 			 * and avoids incompatibilities. It would be nice in			 * future to drop through and process the data.			 *			 * Now that TTCP is starting to be used we ought to 			 * queue this data.			 * But, this leaves one open to an easy denial of		 	 * service attack, and SYN cookies can't defend			 * against this problem. So, we drop the data			 * in the interest of security over speed.			 */			goto discard;		}		goto discard;	case TCP_SYN_SENT:		queued = tcp_rcv_synsent_state_process(sk, skb, th, len);		if (queued >= 0)			return queued;		/* Do step6 onward by hand. */		tcp_urg(sk, skb, th);		__kfree_skb(skb);		tcp_data_snd_check(sk, tp);		return 0;	}	if (tcp_fast_parse_options(skb, th, tp) && tp->rx_opt.saw_tstamp &&	    tcp_paws_discard(sk, skb)) {		if (!th->rst) {			NET_INC_STATS_BH(LINUX_MIB_PAWSESTABREJECTED);			tcp_send_dupack(sk, skb);			goto discard;		}		/* Reset is accepted even if it did not pass PAWS. */	}	/* step 1: check sequence number */	if (!tcp_sequence(tp, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq)) {		if (!th->rst)			tcp_send_dupack(sk, skb);		goto discard;	}	/* step 2: check RST bit */	if(th->rst) {		tcp_reset(sk);		goto discard;	}	tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);	/* step 3: check security and precedence [ignored] */	/*	step 4:	 *	 *	Check for a SYN in window.	 */	if (th->syn && !before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) {		NET_INC_STATS_BH(LINUX_MIB_TCPABORTONSYN);		tcp_reset(sk);		return 1;	}	/* step 5: check the ACK field */	if (th->ack) {		int acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH);		switch(sk->sk_state) {		case TCP_SYN_RECV:			if (acceptable) {				tp->copied_seq = tp->rcv_nxt;				mb();				tcp_set_state(sk, TCP_ESTABLISHED);				sk->sk_state_change(sk);				/* Note, that this wakeup is only for marginal				 * crossed SYN case. Passively open sockets				 * are not waked up, because sk->sk_sleep ==				 * NULL and sk->sk_socket == NULL.				 */				if (sk->sk_socket) {					sk_wake_async(sk,0,POLL_OUT);				}				tp->snd_una = TCP_SKB_CB(skb)->ack_seq;				tp->snd_wnd = ntohs(th->window) <<					      tp->rx_opt.snd_wscale;				tcp_init_wl(tp, TCP_SKB_CB(skb)->ack_seq,					    TCP_SKB_CB(skb)->seq);				/* tcp_ack considers this ACK as duplicate				 * and does not calculate rtt.				 * Fix it at least with timestamps.				 */				if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr &&				    !tp->srtt)					tcp_ack_saw_tstamp(sk, 0, 0);				if (tp->rx_opt.tstamp_ok)					tp->advmss -= TCPOLEN_TSTAMP_ALIGNED;				/* Make sure socket is routed, for				 * correct metrics.				 */				tp->af_specific->rebuild_header(sk);				tcp_init_metrics(sk);				tcp_init_congestion_control(sk);				/* Prevent spurious tcp_cwnd_restart() on				 * first data packet.				 */				tp->lsndtime = tcp_time_stamp;				tcp_initialize_rcv_mss(sk);				tcp_init_buffer_space(sk);				tcp_fast_path_on(tp);			} else {				return 1;			}			break;		case TCP_FIN_WAIT1:			if (tp->snd_una == tp->write_seq) {				tcp_set_state(sk, TCP_FIN_WAIT2);				sk->sk_shutdown |= SEND_SHUTDOWN;				dst_confirm(sk->sk_dst_cache);				if (!sock_flag(sk, SOCK_DEAD))					/* Wake up lingering close() */					sk->sk_state_change(sk);				else {					int tmo;					if (tp->linger2 < 0 ||					    (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq &&					     after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt))) {						tcp_done(sk);						NET_INC_STATS_BH(LINUX_MIB_TCPABORTONDATA);						return 1;					}					tmo = tcp_fin_time(sk);					if (tmo > TCP_TIMEWAIT_LEN) {						inet_csk_reset_keepalive_timer(sk, tmo - TCP_TIMEWAIT_LEN);					} else if (th->fin || sock_owned_by_user(sk)) {						/* Bad case. We could lose such FIN otherwise.						 * It is not a big problem, but it looks confusing						 * and not so rare event. We still can lose it now,						 * if it spins in bh_lock_sock(), but it is really						 * marginal case.						 */						inet_csk_reset_keepalive_timer(sk, tmo);					} else {						tcp_time_wait(sk, TCP_FIN_WAIT2, tmo);						goto discard;					}				}			}			break;		case TCP_CLOSING:			if (tp->snd_una == tp->write_seq) {				tcp_time_wait(sk, TCP_TIME_WAIT, 0);				goto discard;			}			break;		case TCP_LAST_ACK:			if (tp->snd_una == tp->write_seq) {				tcp_update_metrics(sk);				tcp_done(sk);				goto discard;			}			break;		}	} else		goto discard;	/* step 6: check the URG bit */	tcp_urg(sk, skb, th);	/* step 7: process the segment text */	switch (sk->sk_state) {	case TCP_CLOSE_WAIT:	case TCP_CLOSING:	case TCP_LAST_ACK:		if (!before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt))			break;	case TCP_FIN_WAIT1:	case TCP_FIN_WAIT2:		/* RFC 793 says to queue data in these states,		 * RFC 1122 says we MUST send a reset. 		 * BSD 4.4 also does reset.		 */		if (sk->sk_shutdown & RCV_SHUTDOWN) {			if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq &&			    after(TCP_SKB_CB(skb)->end_seq - th->fin, tp->rcv_nxt)) {				NET_INC_STATS_BH(LINUX_MIB_TCPABORTONDATA);				tcp_reset(sk);				return 1;			}		}		/* Fall through */	case TCP_ESTABLISHED: 		tcp_data_queue(sk, skb);		queued = 1;		break;	}	/* tcp_data could move socket to TIME-WAIT */	if (sk->sk_state != TCP_CLOSE) {		tcp_data_snd_check(sk, tp);		tcp_ack_snd_check(sk);	}	if (!queued) { discard:		__kfree_skb(skb);	}	return 0;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/20380731bc2897f2952ae055420972ded4cd786e/tcp_input.c/clean/net/ipv4/tcp_input.c