⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcp_recv.c

📁 最新Minix3源码
💻 C
📖 第 1 页 / 共 3 页
字号:
 { where(); printf("calling tcp_close_connection\n"); }#endif				tcp_close_connection(tcp_conn,					ECONNRESET);				if (connuser)					(void)tcp_su4listen(connuser);				break;			}#if DEBUG { where(); printf("calling tcp_close_connection\n"); }#endif			tcp_close_connection(tcp_conn, ECONNRESET);			break;		}/*	!ACK ?		discard packet		exit*/#if DEBUG & 256 { where(); printf("\n"); }#endif		if (!(tcp_hdr_flags & THF_ACK))			break;/*	state == SYN-RECEIVED ?		SND.UNA <= SEG.ACK <= SND.NXT ?			state= ESTABLISHED		:			<SEG=SEG.ACK><CTL=RST>			exit*/#if DEBUG & 256 { where(); printf("\n"); }#endif	if (tcp_conn->tc_state == TCS_SYN_RECEIVED)	{		if (tcp_LEmod4G(tcp_conn->tc_SND_UNA, seg_ack) &&			tcp_LEmod4G(seg_ack, tcp_conn->tc_SND_NXT))		{			tcp_conn->tc_state= TCS_ESTABLISHED;assert (tcp_check_conn(tcp_conn));#if DEBUG & 2 { where(); tcp_write_state(tcp_conn); }#endifassert(tcp_conn->tc_connuser);			tcp_restart_connect(tcp_conn->tc_connuser);			if (tcp_conn->tc_state == TCS_CLOSED)			{#if DEBUG { where(); printf("connection closed while inuse\n"); }#endif				break;			}		}		else		{			create_RST (tcp_conn, ip_hdr, tcp_hdr);			tcp_restart_write(tcp_conn);			break;		}	}/*	state == ESTABLISHED || state == FIN-WAIT-1 ||		state == FIN-WAIT-2 || state == CLOSE-WAIT ||		state == LAST-ACK || state == TIME_WAIT || state == CLOSING ?		SND.UNA < SEG.ACK <= SND.NXT ?			SND.UNA= SEG.ACK			reply "send ok"			SND.WL1 < SEG.SEQ || (SND.WL1 == SEG.SEQ &&				SND.WL2 <= SEG.ACK ?				SND.WND= SEG.WND				SND.Wl1= SEG.SEQ				SND.WL2= SEG.ACK		SEG.ACK <= SND.UNA ?			ignore ACK		SEG.ACK > SND.NXT ?			<SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>			discard packet			exit*/#if DEBUG & 256 { where(); printf("\n"); }#endif		if (tcp_conn->tc_state == TCS_ESTABLISHED ||			tcp_conn->tc_state == TCS_FIN_WAIT_1 ||			tcp_conn->tc_state == TCS_FIN_WAIT_2 ||			tcp_conn->tc_state == TCS_CLOSE_WAIT ||			tcp_conn->tc_state == TCS_LAST_ACK ||			tcp_conn->tc_state == TCS_TIME_WAIT ||			tcp_conn->tc_state == TCS_CLOSING)		{			if (tcp_LEmod4G(tcp_conn->tc_SND_UNA, seg_ack)				&& tcp_LEmod4G(seg_ack, tcp_conn->				tc_SND_NXT))			{				if (tcp_Lmod4G(tcp_conn->tc_SND_WL1,					seg_seq) || (tcp_conn->					tc_SND_WL1==seg_seq &&					tcp_LEmod4G(tcp_conn->					tc_SND_WL2, seg_ack)))				{					if (seg_wnd > TCP_MAX_WND_SIZE)						seg_wnd= TCP_MAX_WND_SIZE;					if (!seg_wnd)						seg_wnd++;					tcp_conn->tc_SND_WL1= seg_seq;					tcp_conn->tc_SND_WL2= seg_ack;#if SUN_0WND_BUG					if (seg_wnd && seg_ack == tcp_conn->						tc_SND_UNA && tcp_LEmod4G(						seg_ack + seg_wnd,						tcp_conn->tc_SND_NXT) &&						tcp_LEmod4G(seg_ack + seg_wnd,						tcp_conn->tc_snd_cwnd))						seg_wnd= 0;#endif				}				else				{					seg_wnd= tcp_conn->tc_mss;					/* assume 1 segment if not a valid					 * window */				}				tcp_release_retrans(tcp_conn, seg_ack, seg_wnd);				if (tcp_conn->tc_state == TCS_CLOSED)				{#if DEBUG { where(); printf("connection closed while inuse\n"); }#endif					break;				}			}			else if (tcp_Gmod4G(seg_ack,				tcp_conn->tc_SND_NXT))			{				tcp_set_ack_timer(tcp_conn);#if DEBUG { where(); printf("got an ack of something I haven't send\n");   printf("seg_ack= %lu, SND_NXT= %lu\n", seg_ack, tcp_conn->tc_SND_NXT); }#endif				break;			}#if DEBUG & 256 if (!seg_wnd) { where(); printf("SND_UNA= %lu, SND_NXT= %lu\n",	tcp_conn->tc_SND_UNA, tcp_conn->tc_SND_NXT); }#endif			if (!seg_wnd &&			/* tcp_GEmod4G(seg_wnd, tcp_conn->tc_SND_UNA) &&			*/				tcp_Lmod4G(tcp_conn->tc_SND_UNA,				tcp_conn->tc_SND_NXT))			{	/* zero window */#if DEBUG & 256 { where(); printf("setting 0wnd_to\n"); }#endif				clck_untimer(&tcp_conn->tc_minor_timer);				if (!tcp_conn->tc_0wnd_to)				{assert (tcp_conn->tc_rtt);					tcp_conn->tc_0wnd_to=						tcp_conn->tc_rtt;				}				clck_timer(&tcp_conn->tc_major_timer,					get_time()+tcp_conn->tc_0wnd_to,					tcp_zero_wnd_to, tcp_conn-					tcp_conn_table);			}			else			{#if DEBUG & 256 { where(); printf("not setting 0wnd_to\n"); }#endif				if (tcp_conn->tc_0wnd_to)				{#if DEBUG & 256 { where(); printf("resetting 0wnd_to\n"); }#endif					tcp_conn->tc_0wnd_to= 0;					tcp_conn->tc_SND_TRM=						tcp_conn->tc_SND_UNA;					clck_untimer(&tcp_conn->						tc_major_timer);					tcp_restart_write (tcp_conn);				}			}		}/*	state == FIN-WAIT-1 && FIN acknowledged ?		state= FIN-WAIT-2	state == CLOSING && FIN acknowledged ?		state= TIME-WAIT	state == LAST-ACK && FIN acknowledged ?		state= CLOSED	state == TIME-WAIT ?		<SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>		restart 2 MSL timeout*/#if DEBUG & 256 { where(); printf("\n"); }#endif		if (tcp_conn->tc_SND_UNA == tcp_conn->tc_SND_NXT)		{			switch (tcp_conn->tc_state)			{			case TCS_FIN_WAIT_1:				tcp_conn->tc_state= TCS_FIN_WAIT_2;assert (tcp_check_conn(tcp_conn));#if DEBUG { where(); tcp_write_state(tcp_conn); }#endif				break;			case TCS_CLOSING:				tcp_conn->tc_state= TCS_TIME_WAIT;assert (tcp_check_conn(tcp_conn));#if DEBUG { where(); tcp_write_state(tcp_conn); }#endif				tcp_set_time_wait_timer(tcp_conn);				break;			case TCS_LAST_ACK:#if DEBUG & 256 { where(); printf("calling tcp_close_connection\n"); }#endif				tcp_close_connection(tcp_conn, ENOCONN);				break;			}			if (!tcp_conn->tc_mainuser)			{				tcp_close_connection(tcp_conn, ENOCONN);				break;			}		}		if (tcp_conn->tc_state == TCS_TIME_WAIT)		{			tcp_set_ack_timer(tcp_conn);			tcp_set_time_wait_timer(tcp_conn);		}/*	process data...*/#if DEBUG & 256 { where(); printf("\n"); }#endif		tcp_extract_ipopt(tcp_conn, ip_hdr);		tcp_extract_tcpopt(tcp_conn, tcp_hdr);		if (data_length)		{			if (tcp_LEmod4G(seg_seq, tcp_conn->tc_RCV_NXT))				process_data (tcp_conn, tcp_hdr,					tcp_hdr_len, tcp_pack,					data_length);			else				process_advanced_data (tcp_conn,					tcp_hdr, tcp_hdr_len, tcp_pack,					data_length);			if (tcp_conn->tc_state == TCS_CLOSED)				break;			tcp_conn->tc_flags |= TCF_SEND_ACK;#if DEBUG & 256 { where(); printf("tcp_conn_table[%d].tc_flags= 0x%x\n", 	tcp_conn-tcp_conn_table, tcp_conn->tc_flags); }#endif			tcp_restart_write (tcp_conn);			if (tcp_conn->tc_state == TCS_CLOSED)				break;		}/*	FIN ?		reply pending receives		advace RCV.NXT over the FIN		<SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>		state == SYN-RECEIVED || state == ESTABLISHED ?			state= CLOSE-WAIT		state == FIN-WAIT-1 ?			state= CLOSING		state == FIN-WAIT-2 ?			state= TIME-WAIT		state == TIME-WAIT ?			restart the TIME-WAIT timer	exit*/#if DEBUG & 256 { where(); printf("\n"); }#endif		if ((tcp_hdr_flags & THF_FIN) && tcp_LEmod4G(seg_seq,			tcp_conn->tc_RCV_NXT))		{			switch (tcp_conn->tc_state)			{			case TCS_SYN_RECEIVED:				break;			case TCS_ESTABLISHED:				tcp_conn->tc_state= TCS_CLOSE_WAIT;assert (tcp_check_conn(tcp_conn));#if DEBUG { where(); tcp_write_state(tcp_conn); }#endif				break;			case TCS_FIN_WAIT_1:				tcp_conn->tc_state= TCS_CLOSING;assert (tcp_check_conn(tcp_conn));#if DEBUG { where(); tcp_write_state(tcp_conn); }#endif				break;			case TCS_FIN_WAIT_2:				tcp_conn->tc_state= TCS_TIME_WAIT;assert (tcp_check_conn(tcp_conn));#if DEBUG { where(); tcp_write_state(tcp_conn); }#endif				/* drops through */			case TCS_TIME_WAIT:				tcp_set_time_wait_timer(tcp_conn);				break;			}			if (!(tcp_conn->tc_flags & TCF_FIN_RECV))			{				tcp_conn->tc_RCV_NXT++;				tcp_conn->tc_flags |= TCF_FIN_RECV;#if DEBUG & 256 { where(); printf("tcp_conn_table[%d].tc_flags= 0x%x\n", 	tcp_conn-tcp_conn_table, tcp_conn->tc_flags); }#endif			}			tcp_set_ack_timer(tcp_conn);			if (tcp_conn->tc_readuser)				tcp_restart_fd_read(tcp_conn);		}		break;	default:		printf("unknown state: tcp_conn->tc_state== %d\n",			tcp_conn->tc_state);		break;	}	bf_afree(ip_pack);	bf_afree(tcp_pack);}PRIVATE void process_data(tcp_conn, tcp_hdr, tcp_hdr_len, tcp_data,	data_len)tcp_conn_t *tcp_conn;tcp_hdr_t *tcp_hdr;int tcp_hdr_len;acc_t *tcp_data;int data_len;{	u32_t lo_seq, hi_seq, urg_seq, seq_nr;	u16_t urgptr;	int tcp_hdr_flags;	unsigned int offset;	acc_t *all_data, *tmp_data, *rcvd_data;#if DEBUG & 256 { where(); printf("in process data\n"); }#endif	seq_nr= ntohl(tcp_hdr->th_seq_nr);	urgptr= ntohs(tcp_hdr->th_urgptr);	while (tcp_data)	{assert (tcp_check_conn(tcp_conn));		all_data= bf_cut(tcp_data, tcp_hdr_len, data_len);		tcp_data= 0;		lo_seq= seq_nr;		tcp_hdr_flags= tcp_hdr->th_flags & TH_FLAGS_MASK;		if (tcp_hdr_flags & THF_URG)		{			urg_seq= lo_seq+ urgptr;			tcp_conn->tc_RCV_HI= tcp_conn->tc_RCV_LO+				tcp_conn->tc_rcv_wnd+tcp_conn->				tc_urg_wnd;			if (tcp_GEmod4G(urg_seq, tcp_conn->tc_RCV_HI))				urg_seq= tcp_conn->tc_RCV_HI;			if (tcp_Gmod4G(urg_seq, tcp_conn->tc_RCV_UP))				tcp_conn->tc_RCV_UP= urg_seq;		}		if (tcp_hdr_flags & THF_SYN)			lo_seq++;		if (tcp_hdr_flags & THF_PSH)		{			tcp_conn->tc_flags |= TCF_RCV_PUSH;#if DEBUG & 256 { where(); printf("tcp_conn_table[%d].tc_flags= 0x%x\n", 	tcp_conn-tcp_conn_table, tcp_conn->tc_flags); }#endif		}		if (tcp_Lmod4G(lo_seq, tcp_conn->tc_RCV_NXT))		{			offset= tcp_conn->tc_RCV_NXT-lo_seq;			tmp_data= bf_cut(all_data, offset, data_len-				offset);			bf_afree(all_data);			lo_seq += offset;			data_len -= offset;			all_data= tmp_data;			tmp_data= 0;		}		assert (lo_seq == tcp_conn->tc_RCV_NXT);		hi_seq= lo_seq+data_len;		if (tcp_Gmod4G(hi_seq, tcp_conn->tc_RCV_HI))		{			data_len= tcp_conn->tc_RCV_HI-lo_seq;			tmp_data= bf_cut(all_data, 0, data_len);			bf_afree(all_data);			all_data= tmp_data;			hi_seq= lo_seq+data_len;			tcp_hdr_flags &= ~THF_FIN;		}		assert (tcp_LEmod4G (hi_seq, tcp_conn->tc_RCV_HI));#if DEBUG & 256 { where(); printf("in process data: lo_seq= %lu, hi_seq= %lu\n",	lo_seq, hi_seq); }#endif		rcvd_data= tcp_conn->tc_rcvd_data;		tcp_conn->tc_rcvd_data= 0;		tmp_data= bf_append(rcvd_data, all_data);		if (tcp_conn->tc_state == TCS_CLOSED)		{#if DEBUG { where(); printf("connection closed while inuse\n"); }#endif			bf_afree(tmp_data);			return;		}		tcp_conn->tc_rcvd_data= tmp_data;		tcp_conn->tc_RCV_NXT= hi_seq;		assert (tcp_conn->tc_RCV_LO + bf_bufsize(tcp_conn->			tc_rcvd_data) == tcp_conn->tc_RCV_NXT);				if (tcp_hdr_flags & THF_FIN)		{#if DEBUG { where(); printf("got a FIN\n"); }#endif			tcp_conn->tc_RCV_NXT++;			tcp_conn->tc_flags |= TCF_FIN_RECV;#if DEBUG & 16 { where(); printf("tcp_conn_table[%d].tc_flags= 0x%x\n", 	tcp_conn-tcp_conn_table, tcp_conn->tc_flags); }#endif		}		tcp_set_ack_timer(tcp_conn);		while (tcp_conn->tc_rcv_queue)		{			tmp_data= tcp_conn->tc_rcv_queue;			assert (tmp_data->acc_length >= TCP_MIN_HDR_SIZE);			tcp_hdr= (tcp_hdr_t *)ptr2acc_data(tmp_data);			lo_seq= tcp_hdr->th_seq_nr;			/* th_seq_nr is changed to host byte order */			if (tcp_Gmod4G(lo_seq, tcp_conn->tc_RCV_NXT))				break;			tcp_hdr_len= (tcp_hdr->th_data_off &				TH_DO_MASK) >> 2;			data_len= tcp_hdr->th_chksum-tcp_hdr_len;			if (tcp_LEmod4G(lo_seq+data_len, tcp_conn->				tc_RCV_NXT))			{				tcp_conn->tc_rcv_queue= tmp_data->					acc_ext_link;				bf_afree(tmp_data);				continue;			}			tcp_data= tmp_data;			seq_nr= tcp_hdr->th_seq_nr;			urgptr= tcp_hdr->th_urgptr;			break;		}	}assert (tcp_check_conn(tcp_conn));	if (tcp_conn->tc_readuser)		tcp_restart_fd_read(tcp_conn);	else if (!tcp_conn->tc_mainuser)	{#if DEBUG { where(); printf("calling tcp_close_connection\n"); }#endif		tcp_close_connection (tcp_conn, ENOCONN);	}assert (tcp_check_conn(tcp_conn));}PRIVATE void process_advanced_data(tcp_conn, tcp_hdr, tcp_hdr_len,	tcp_data, data_len)tcp_conn_t *tcp_conn;tcp_hdr_t *tcp_hdr;int tcp_hdr_len;acc_t *tcp_data;int data_len;{	u32_t seg_seq, seg_hi;	u16_t seg_up;	acc_t *hdr_acc, *next_acc, **tail_acc_ptr, *head_acc, *data_acc,		*tmp_acc;	tcp_hdr_t *tmp_hdr;	int tmp_hdr_len;#if DEBUG & 256 { where(); printf ("processing advanced data\n"); }#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -