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

📄 tcp_recv.c

📁 最新Minix3源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	hdr_acc= bf_memreq(tcp_hdr_len);	/* make fresh header */	if (tcp_conn->tc_state == TCS_CLOSED)	{#if DEBUG { where(); printf("connection closed while inuse\n"); }#endif		bf_afree(hdr_acc);		return;	}	assert (hdr_acc->acc_length == tcp_hdr_len);	tmp_hdr= (tcp_hdr_t *)ptr2acc_data(hdr_acc);#if DEBUG & 256 { where(); printf("doing memcpy\n"); }#endif	memcpy ((char *)tmp_hdr, (char *)tcp_hdr, tcp_hdr_len);	tcp_hdr= tmp_hdr;	data_acc= bf_cut (tcp_data, tcp_hdr_len, data_len);	seg_seq= ntohl(tcp_hdr->th_seq_nr);	tcp_hdr->th_seq_nr= seg_seq;	/* seq_nr in host format */	if (tcp_hdr->th_flags & THF_URG)	{		seg_up= ntohs(tcp_hdr->th_urgptr);		tcp_hdr->th_urgptr= seg_up;					/* urgptr in host format */		tcp_conn->tc_RCV_HI= tcp_conn->tc_RCV_LO+			tcp_conn->tc_rcv_wnd+tcp_conn->tc_urg_wnd;	}	assert (!(tcp_hdr->th_flags & THF_SYN));	assert (tcp_Gmod4G(seg_seq, tcp_conn->tc_RCV_NXT));	tcp_hdr->th_flags &= ~THF_FIN;	/* it is too difficult to		preserve a FIN */	seg_hi= seg_seq + data_len;	if (tcp_Gmod4G(seg_hi, tcp_conn->tc_RCV_HI))	{		seg_hi= tcp_conn->tc_RCV_HI;		data_len= seg_hi-seg_seq;		if (!data_len)		{			bf_afree(hdr_acc);			bf_afree(data_acc);			return;		}#if DEBUG { where(); printf("Cutting packet\n"); }#endif		tmp_acc= bf_cut(data_acc, 0, data_len);		bf_afree(data_acc);		data_acc= tmp_acc;	}	hdr_acc->acc_next= data_acc;	hdr_acc->acc_ext_link= 0;	head_acc= tcp_conn->tc_rcv_queue;	tcp_conn->tc_rcv_queue= 0;	tail_acc_ptr= 0;	next_acc= head_acc;	while (next_acc)	{		assert (next_acc->acc_length >= TCP_MIN_HDR_SIZE);		tmp_hdr= (tcp_hdr_t *)ptr2acc_data(next_acc);		if (tcp_Lmod4G(seg_seq, tmp_hdr->th_seq_nr))		{#if DEBUG & 256 { where(); printf("calling merge_packs\n"); } #endif			next_acc= merge_packs(hdr_acc, next_acc);			hdr_acc= 0;			if (tail_acc_ptr)			{assert (*tail_acc_ptr);				(*tail_acc_ptr)->acc_ext_link= 0;#if DEBUG & 256 { where(); printf("calling merge_packs\n"); } #endif				*tail_acc_ptr= merge_packs(					*tail_acc_ptr, next_acc);			}			else				head_acc= next_acc;			break;		}		if (!tail_acc_ptr)			tail_acc_ptr=  &head_acc;		else			tail_acc_ptr= &(*tail_acc_ptr)->acc_ext_link;		next_acc= next_acc->acc_ext_link;	}	if (hdr_acc)	{		next_acc= hdr_acc;		hdr_acc= 0;		if (tail_acc_ptr)		{			if (*tail_acc_ptr)			{				(*tail_acc_ptr)->acc_ext_link= 0;#if DEBUG & 256 { where(); printf("calling merge_packs\n"); } #endif				*tail_acc_ptr= merge_packs(					*tail_acc_ptr, next_acc);			}			else				*tail_acc_ptr= next_acc;		}		else			head_acc= next_acc;	}	if (tcp_conn->tc_state == TCS_CLOSED)	{		while (head_acc)		{			next_acc= head_acc->acc_ext_link;			bf_afree(head_acc);			head_acc= next_acc;		}		return;	}	tcp_conn->tc_rcv_queue= head_acc;}				PRIVATE acc_t *merge_packs(first, next)acc_t *first;acc_t *next;{	tcp_hdr_t *first_hdr, *next_hdr;	int first_hdr_len, next_hdr_len, first_data_len, next_data_len;	acc_t *next_acc, *tmp_acc;	assert (first->acc_length >= TCP_MIN_HDR_SIZE);	assert (next->acc_length >= TCP_MIN_HDR_SIZE);	first_hdr= (tcp_hdr_t *)ptr2acc_data(first);	next_hdr= (tcp_hdr_t *)ptr2acc_data(next);	first_hdr_len= (first_hdr->th_data_off & TH_DO_MASK) >>2;	next_hdr_len= (next_hdr->th_data_off & TH_DO_MASK) >> 2;	first_data_len= first_hdr->th_chksum-first_hdr_len;	next_data_len= next_hdr->th_chksum-next_hdr_len;assert (tcp_LEmod4G(first_hdr->th_seq_nr, next_hdr->th_seq_nr));assert (first_hdr_len + first_data_len == bf_bufsize(first));#if DEBUG if (next_hdr_len + next_data_len != bf_bufsize(next)) { ip_panic(( "fatal error: %d + %d != %d\n", next_hdr_len, next_data_len,    bf_bufsize(next) )); }#endifassert (next_hdr_len + next_data_len == bf_bufsize(next));	if (tcp_Lmod4G(first_hdr->th_seq_nr+first_data_len,		next_hdr->th_seq_nr))	{		first->acc_ext_link= next;		return first;	}	if (first_hdr->th_seq_nr == next_hdr->th_seq_nr)		if (first_data_len <= next_data_len)		{			bf_afree(first);			return next;		}		else		{			first->acc_ext_link= next->acc_ext_link;			bf_afree(next);			return first;		}	if (tcp_GEmod4G(first_hdr->th_seq_nr+first_data_len,		next_hdr->th_seq_nr+next_data_len))	{		first->acc_ext_link= next->acc_ext_link;		bf_afree(next);		return first;	}	first_data_len= next_hdr->th_seq_nr-first_hdr->th_seq_nr;	first_hdr->th_chksum= first_data_len+first_hdr_len+		next_data_len;	tmp_acc= bf_cut(first, 0, first_hdr_len + first_data_len);	bf_afree(first);	first= tmp_acc;	if (next_hdr->th_flags & THF_PSH)		first_hdr->th_flags |= THF_PSH;	if (next_hdr->th_flags & THF_URG)	{		if (!(first_hdr->th_flags & THF_URG))		{			first_hdr->th_flags |= THF_URG;			first_hdr->th_urgptr= next_hdr->th_seq_nr+				next_hdr->th_urgptr-				first_hdr->th_seq_nr;		}		else if (next_hdr->th_seq_nr+next_hdr->th_urgptr-			first_hdr->th_seq_nr > first_hdr->th_urgptr)			first_hdr->th_urgptr= next_hdr->th_seq_nr+				next_hdr->th_urgptr-				first_hdr->th_seq_nr;	}	next_acc= next->acc_ext_link;	tmp_acc= bf_cut(next, next_hdr_len ,next_data_len);	bf_afree(next);	next= tmp_acc;	tmp_acc= bf_append (first, next);	tmp_acc->acc_ext_link= next_acc;	return tmp_acc;}PRIVATE void create_RST(tcp_conn, ip_hdr, tcp_hdr)tcp_conn_t *tcp_conn;ip_hdr_t *ip_hdr;tcp_hdr_t *tcp_hdr;{	acc_t *tmp_ipopt, *tmp_tcpopt;	ip_hdropt_t ip_hdropt;	tcp_hdropt_t tcp_hdropt;	acc_t *RST_acc;	ip_hdr_t *RST_ip_hdr;	tcp_hdr_t *RST_tcp_hdr;	char *ptr2RSThdr;	size_t pack_size;	tmp_ipopt= tcp_conn->tc_remipopt;	if (tmp_ipopt)		tmp_ipopt->acc_linkC++;	tmp_tcpopt= tcp_conn->tc_remtcpopt;	if (tmp_tcpopt)		tmp_tcpopt->acc_linkC++;	tcp_extract_ipopt (tcp_conn, ip_hdr);	tcp_extract_tcpopt (tcp_conn, tcp_hdr);	RST_acc= tcp_make_header (tcp_conn, &RST_ip_hdr, &RST_tcp_hdr,		(acc_t *)0);	if (!RST_acc)	{#if DEBUG { where(); printf("connection closed while inuse\n"); }#endif		return;	}	if (tcp_conn->tc_remipopt)		bf_afree(tcp_conn->tc_remipopt);	tcp_conn->tc_remipopt= tmp_ipopt;	if (tcp_conn->tc_remtcpopt)		bf_afree(tcp_conn->tc_remtcpopt);	tcp_conn->tc_remtcpopt= tmp_tcpopt;	RST_ip_hdr->ih_src= ip_hdr->ih_dst;	RST_ip_hdr->ih_dst= ip_hdr->ih_src;	RST_tcp_hdr->th_srcport= tcp_hdr->th_dstport;	RST_tcp_hdr->th_dstport= tcp_hdr->th_srcport;	if (tcp_hdr->th_flags & THF_ACK)	{		RST_tcp_hdr->th_seq_nr= tcp_hdr->th_ack_nr;		RST_tcp_hdr->th_flags= THF_RST;	}	else	{		RST_tcp_hdr->th_seq_nr= 0;		RST_tcp_hdr->th_ack_nr= htonl(ntohl(tcp_hdr->th_seq_nr)+			tcp_hdr->th_chksum-((tcp_hdr->th_data_off &			TH_DO_MASK) >> 2)+ (tcp_hdr->th_flags &			THF_SYN ? 1 : 0) + (tcp_hdr->th_flags &			THF_FIN ? 1 : 0));		RST_tcp_hdr->th_flags= THF_RST|THF_ACK;	}	pack_size= bf_bufsize(RST_acc);	RST_ip_hdr->ih_length= htons(pack_size);	RST_tcp_hdr->th_window= htons(tcp_conn->tc_rcv_wnd);	RST_tcp_hdr->th_chksum= 0;	RST_tcp_hdr->th_chksum= ~tcp_pack_oneCsum (RST_acc, pack_size);		if (tcp_conn->tc_frag2send)		bf_afree(tcp_conn->tc_frag2send);	tcp_conn->tc_frag2send= RST_acc;}PUBLIC void tcp_restart_fd_read (tcp_conn)tcp_conn_t *tcp_conn;{	tcp_fd_t *new_fd, *hi_fd, *urgent_fd, *normal_fd, *tcp_fd;#if DEBUG & 256 { where(); printf("tcp_restart_fd_read called\n"); }#endif	do	{		tcp_fd= tcp_conn->tc_readuser;		if (tcp_fd)			fd_read (tcp_fd);		else			tcp_fd= &tcp_fd_table[TCP_FD_NR-1];		if (!tcp_conn->tc_readuser)		{			urgent_fd= 0;			normal_fd= 0;			for (new_fd= tcp_fd+1, hi_fd=				&tcp_fd_table[TCP_FD_NR]; new_fd<hi_fd;				new_fd++)				switch_read_fd(tcp_conn, new_fd,					&urgent_fd, &normal_fd);			for (new_fd= tcp_fd_table, hi_fd= tcp_fd+1;				new_fd < hi_fd; new_fd++)				switch_read_fd(tcp_conn, new_fd,					&urgent_fd, &normal_fd);			if (urgent_fd)				tcp_fd= urgent_fd;			else				tcp_fd= normal_fd;			tcp_conn->tc_readuser= tcp_fd;		}		else			return;	} while (tcp_conn->tc_readuser);}PRIVATE void switch_read_fd (tcp_conn, new_fd, ref_urg_fd,	ref_norm_fd)tcp_conn_t *tcp_conn;tcp_fd_t *new_fd, **ref_urg_fd, **ref_norm_fd;{	if (!(new_fd->tf_flags & TFF_INUSE))		return;	if (new_fd->tf_conn != tcp_conn)		return;	if (!(new_fd->tf_flags & TFF_READ_IP))		return;	if (new_fd->tf_flags & TFF_RECV_URG)	{		if (!*ref_urg_fd)			*ref_urg_fd= new_fd;	}	else	{		if (!*ref_norm_fd)			*ref_norm_fd= new_fd;	}}PRIVATE void fd_read(tcp_fd)tcp_fd_t *tcp_fd;{	tcp_conn_t *tcp_conn;	size_t data_size, read_size;	acc_t * data;	int urg, result;	int more2write;	more2write= FALSE;	tcp_conn= tcp_fd->tf_conn;	assert (tcp_fd->tf_flags & TFF_READ_IP);	if (tcp_conn->tc_state == TCS_CLOSED)	{		tcp_conn->tc_readuser= 0;#if DEBUG { where(); printf("calling tcp_reply_read\n"); }#endif		if (tcp_fd->tf_read_offset)			tcp_reply_read (tcp_fd, tcp_fd->tf_read_offset);		else			tcp_reply_read (tcp_fd, tcp_conn->tc_error);		return;	}#if URG_PROPERLY_IMPLEMENTED	urg= (tcp_GEmod4G(tcp_conn->tc_RCV_UP, tcp_conn->tc_RCV_LO) &&		tcp_Lmod4G(tcp_conn->tc_RCV_UP, tcp_conn->tc_RCV_NXT));#else#define urg 0#endif	if (urg && !(tcp_fd->tf_flags & TFF_RECV_URG))	{		tcp_conn->tc_readuser= 0;#if DEBUG { where(); printf("calling tcp_reply_read\n"); }#endif		if (tcp_fd->tf_read_offset)			tcp_reply_read (tcp_fd, tcp_fd->tf_read_offset);		else			tcp_reply_read (tcp_fd, EURG);		return;	}	else if (!urg && (tcp_fd->tf_flags & TFF_RECV_URG))	{		tcp_conn->tc_readuser= 0;#if DEBUG { where(); printf("calling tcp_reply_read\n"); }#endif		if (tcp_fd->tf_read_offset)			tcp_reply_read (tcp_fd, tcp_fd->tf_read_offset);		else			tcp_reply_read(tcp_fd, ENOURG);		return;	}	data_size= tcp_conn->tc_RCV_NXT-tcp_conn->tc_RCV_LO;	if (tcp_conn->tc_flags & TCF_FIN_RECV)		data_size--;	if (urg)		read_size= tcp_conn->tc_RCV_UP+1-tcp_conn->tc_RCV_LO;	else		read_size= data_size;	if (read_size>tcp_fd->tf_read_count)		read_size= tcp_fd->tf_read_count;	if (read_size)	{		if (read_size == data_size)			data= bf_dupacc(tcp_conn->tc_rcvd_data);		else			data= bf_cut(tcp_conn->tc_rcvd_data, 0, read_size);		result= (*tcp_fd->tf_put_userdata) (tcp_fd->tf_srfd,			tcp_fd->tf_read_offset, data, FALSE);		if (tcp_conn->tc_state == TCS_CLOSED)		{#if DEBUG { where(); printf("connection closed while inuse\n"); }#endif			return;		}		if (result<0)		{			tcp_conn->tc_readuser= 0;#if DEBUG { where(); printf("calling tcp_reply_read\n"); }#endif			if (tcp_fd->tf_read_offset)				tcp_reply_read(tcp_fd, tcp_fd->					tf_read_offset);			else				tcp_reply_read(tcp_fd, result);			return;		}		tcp_fd->tf_read_offset += read_size;		tcp_fd->tf_read_count -= read_size;		if (data_size == read_size)		{			bf_afree(tcp_conn->tc_rcvd_data);			tcp_conn->tc_rcvd_data= 0;		}		else		{			data= tcp_conn->tc_rcvd_data;			tcp_conn->tc_rcvd_data= bf_cut(data,				read_size, data_size-read_size);			bf_afree(data);		}		tcp_conn->tc_RCV_LO += read_size;		data_size -= read_size;	}	if (tcp_conn->tc_RCV_HI-tcp_conn->tc_RCV_LO < (tcp_conn->		tc_rcv_wnd >> 2))	{		tcp_conn->tc_RCV_HI= tcp_conn->tc_RCV_LO + 			tcp_conn->tc_rcv_wnd;		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		more2write= TRUE;	}	if (!data_size && (tcp_conn->tc_flags & TCF_RCV_PUSH))	{		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_fd->tf_read_offset)		{			tcp_conn->tc_readuser= 0;#if DEBUG & 256 { where(); printf("calling tcp_reply_read\n"); }#endif			tcp_reply_read (tcp_fd, tcp_fd->tf_read_offset);			if (more2write)				tcp_restart_write(tcp_conn);			return;		}	}	if ((tcp_conn->tc_flags & TCF_FIN_RECV) ||		!tcp_fd->tf_read_count)	{		tcp_conn->tc_readuser= 0;#if DEBUG & 256 { where(); printf("calling tcp_reply_read\n"); }#endif		tcp_reply_read (tcp_fd, tcp_fd->tf_read_offset);		if (more2write)			tcp_restart_write(tcp_conn);		return;	}	if (more2write)		tcp_restart_write(tcp_conn);}

⌨️ 快捷键说明

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