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

📄 tcp_send.c

📁 minix3的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	DIFBLOCK(0x10, (tcp_conn->tc_fd == 0),		printf("conn[%d] timeout in abondoned connection\n",		tcp_conn-tcp_conn_table));	/* At this point, we have do a retransmission, or send a zero window	 * probe, which is almost the same.	 */	DBLOCK(0x20, printf("tcp_send_timeout: conn[%d] una= %lu, rtt= %ldms\n",		tcp_conn-tcp_conn_table,		(unsigned long)tcp_conn->tc_SND_UNA, rtt*1000/HZ));	/* Update threshold sequence number for retransmission calculation. */	if (tcp_Gmod4G(tcp_conn->tc_SND_TRM, tcp_conn->tc_rt_threshold))		tcp_conn->tc_rt_threshold= tcp_conn->tc_SND_TRM;	tcp_conn->tc_SND_TRM= tcp_conn->tc_SND_UNA;	if (tcp_conn->tc_flags & TCF_PMTU &&		curr_time > stt+TCP_PMTU_BLACKHOLE)	{		/* We can't tell the difference between a PMTU blackhole 		 * and a broken link. Assume a PMTU blackhole, and switch		 * off PMTU discovery.		 */		DBLOCK(1, printf(			"tcp[%d]: PMTU blackhole (or broken link) on route to ",			tcp_conn-tcp_conn_table);			writeIpAddr(tcp_conn->tc_remaddr);			printf(", max mtu = %u\n", tcp_conn->tc_max_mtu););		tcp_conn->tc_flags &= ~TCF_PMTU;		tcp_conn->tc_mtutim= curr_time;		if (tcp_conn->tc_max_mtu > IP_DEF_MTU)			tcp_conn->tc_mtu= IP_DEF_MTU;	}	mss= tcp_conn->tc_mtu-IP_TCP_MIN_HDR_SIZE;	mss2= 2*mss;	if (tcp_conn->tc_snd_cwnd == tcp_conn->tc_SND_UNA)		tcp_conn->tc_snd_cwnd++;	if (tcp_Gmod4G(tcp_conn->tc_snd_cwnd, tcp_conn->tc_SND_UNA + mss2))	{		tcp_conn->tc_snd_cwnd= tcp_conn->tc_SND_UNA + mss2;		if (tcp_Gmod4G(tcp_conn->tc_SND_TRM, tcp_conn->tc_snd_cwnd))			tcp_conn->tc_SND_TRM= tcp_conn->tc_snd_cwnd;		tcp_conn->tc_snd_cthresh /= 2;		if (tcp_conn->tc_snd_cthresh < mss2)			tcp_conn->tc_snd_cthresh= mss2;	}	if (curr_time-stt > tcp_conn->tc_rt_dead)	{		tcp_close_connection(tcp_conn, ETIMEDOUT);		return;	}	timeout= (curr_time-stt) >> 3;	if (timeout < rtt)		timeout= rtt;	timeout += curr_time;	DBLOCK(0x20, printf(	"tcp_send_timeout: conn[%d] setting timer to %ld ms (+%ld ms)\n",		tcp_conn-tcp_conn_table, timeout*1000/HZ,		(timeout-curr_time)*1000/HZ));	clck_timer(&tcp_conn->tc_transmit_timer, timeout,		tcp_send_timeout, tcp_conn-tcp_conn_table);#if 0	if (tcp_conn->tc_rt_seq == 0)	{		printf("tcp_send_timeout: conn[%d]: setting tc_rt_time\n",			tcp_conn-tcp_conn_table);		tcp_conn->tc_rt_time= curr_time-rtt;		tcp_conn->tc_rt_seq= tcp_conn->tc_SND_UNA;	}#endif	if (tcp_conn->tc_state == TCS_SYN_SENT ||		(curr_time-stt >= tcp_conn->tc_ttl*HZ))	{		new_ttl= tcp_conn->tc_ttl+1;		if (new_ttl> IP_MAX_TTL)			new_ttl= IP_MAX_TTL;		tcp_conn->tc_ttl= new_ttl;	}	tcp_conn_write(tcp_conn, 0);}PUBLIC void tcp_fd_write(tcp_conn)tcp_conn_t *tcp_conn;{	tcp_fd_t *tcp_fd;	int urg, nourg, push;	u32_t max_seq;	size_t max_trans, write_count;	acc_t *data, *send_data;	assert(tcp_conn->tc_busy);	tcp_fd= tcp_conn->tc_fd;	if ((tcp_fd->tf_flags & TFF_IOCTL_IP) &&		!(tcp_fd->tf_flags & TFF_WRITE_IP))	{		if (tcp_fd->tf_ioreq != NWIOTCPSHUTDOWN)			return;		DBLOCK(0x10, printf("NWIOTCPSHUTDOWN\n"));		if (tcp_conn->tc_state == TCS_CLOSED)		{			tcp_reply_ioctl (tcp_fd, tcp_conn->tc_error);			return;		}		if (!(tcp_conn->tc_flags & TCF_FIN_SENT))		{			DBLOCK(0x10, printf("calling tcp_shutdown\n"));			tcp_shutdown (tcp_conn);		}		else		{			if (tcp_conn->tc_SND_UNA == tcp_conn->tc_SND_NXT)			{				tcp_reply_ioctl (tcp_fd, NW_OK);				DBLOCK(0x10, printf("shutdown completed\n"));			}			else			{				DBLOCK(0x10,					printf("shutdown still inprogress\n"));			}		}		return;	}	assert (tcp_fd->tf_flags & TFF_WRITE_IP);	if (tcp_conn->tc_state == TCS_CLOSED)	{		if (tcp_fd->tf_write_offset)		{			tcp_reply_write(tcp_fd,				tcp_fd->tf_write_offset);		}		else			tcp_reply_write(tcp_fd, tcp_conn->tc_error);		return;	}	urg= (tcp_fd->tf_flags & TFF_WR_URG);	push= (tcp_fd->tf_flags & TFF_PUSH_DATA);	max_seq= tcp_conn->tc_SND_UNA + TCP_MAX_SND_WND_SIZE;	max_trans= max_seq - tcp_conn->tc_SND_NXT;	if (tcp_fd->tf_write_count <= max_trans)		write_count= tcp_fd->tf_write_count;	else		write_count= max_trans;	if (write_count)	{		if (tcp_conn->tc_flags & TCF_BSD_URG)		{			if (tcp_Gmod4G(tcp_conn->tc_SND_NXT,				tcp_conn->tc_SND_UNA))			{				nourg= tcp_LEmod4G(tcp_conn->tc_SND_UP,					tcp_conn->tc_SND_UNA);				if ((urg && nourg) || (!urg && !nourg))				{					DBLOCK(0x20,						printf("not sending\n"));					return;				}			}		}		data= (*tcp_fd->tf_get_userdata)			(tcp_fd->tf_srfd, tcp_fd->tf_write_offset,			write_count, FALSE);		if (!data)		{			if (tcp_fd->tf_write_offset)			{				tcp_reply_write(tcp_fd,					tcp_fd->tf_write_offset);			}			else				tcp_reply_write(tcp_fd, EFAULT);			return;		}		tcp_fd->tf_write_offset += write_count;		tcp_fd->tf_write_count -= write_count;		send_data= tcp_conn->tc_send_data;		tcp_conn->tc_send_data= 0;		send_data= bf_append(send_data, data);		tcp_conn->tc_send_data= send_data;		tcp_conn->tc_SND_NXT += write_count;		if (urg)		{			if (tcp_conn->tc_flags & TCF_BSD_URG)				tcp_conn->tc_SND_UP= tcp_conn->tc_SND_NXT;			else				tcp_conn->tc_SND_UP= tcp_conn->tc_SND_NXT-1;		}		if (push && !tcp_fd->tf_write_count)			tcp_conn->tc_SND_PSH= tcp_conn->tc_SND_NXT;	}	if (!tcp_fd->tf_write_count)	{		tcp_reply_write(tcp_fd, tcp_fd->tf_write_offset);	}}PUBLIC unsigned tcp_sel_write(tcp_conn)tcp_conn_t *tcp_conn;{	tcp_fd_t *tcp_fd;	int urg, nourg;	u32_t max_seq;	size_t max_trans;	tcp_fd= tcp_conn->tc_fd;	if (tcp_conn->tc_state == TCS_CLOSED)		return 1;		urg= (tcp_fd->tf_flags & TFF_WR_URG);	max_seq= tcp_conn->tc_SND_UNA + TCP_MAX_SND_WND_SIZE;	max_trans= max_seq - tcp_conn->tc_SND_NXT;	if (max_trans)	{		if (tcp_conn->tc_flags & TCF_BSD_URG)		{			if (tcp_Gmod4G(tcp_conn->tc_SND_NXT,				tcp_conn->tc_SND_UNA))			{				nourg= tcp_LEmod4G(tcp_conn->tc_SND_UP,					tcp_conn->tc_SND_UNA);				if ((urg && nourg) || (!urg && !nourg))				{					DBLOCK(0x20,						printf("not sending\n"));					return 0;				}			}		}		return 1;	}	return 0;}PUBLIC voidtcp_rsel_write(tcp_conn)tcp_conn_t *tcp_conn;{	tcp_fd_t *tcp_fd;	if (tcp_sel_write(tcp_conn) == 0)		return;	tcp_fd= tcp_conn->tc_fd;	tcp_fd->tf_flags &= ~TFF_SEL_WRITE;	if (tcp_fd->tf_select_res)		tcp_fd->tf_select_res(tcp_fd->tf_srfd, SR_SELECT_WRITE);	else		printf("tcp_rsel_write: no select_res\n");}/*tcp_shutdown*/PUBLIC void tcp_shutdown(tcp_conn)tcp_conn_t *tcp_conn;{	switch (tcp_conn->tc_state)	{	case TCS_CLOSED:	case TCS_LISTEN:	case TCS_SYN_SENT:	case TCS_SYN_RECEIVED:		tcp_close_connection(tcp_conn, ENOTCONN);		return;	}	if (tcp_conn->tc_flags & TCF_FIN_SENT)		return;	tcp_conn->tc_flags |= TCF_FIN_SENT;	tcp_conn->tc_flags &= ~TCF_NO_PUSH;	tcp_conn->tc_SND_NXT++;	tcp_conn->tc_SND_PSH= tcp_conn->tc_SND_NXT;	assert (tcp_check_conn(tcp_conn) ||		(tcp_print_conn(tcp_conn), printf("\n"), 0));	tcp_conn_write(tcp_conn, 1);	/* Start the timer */	tcp_set_send_timer(tcp_conn);}PUBLIC void tcp_set_send_timer(tcp_conn)tcp_conn_t *tcp_conn;{	clock_t curr_time;	clock_t rtt;	assert(tcp_conn->tc_state != TCS_CLOSED);	assert(tcp_conn->tc_state != TCS_LISTEN);	curr_time= get_time();	rtt= tcp_conn->tc_rtt;	DBLOCK(0x20, printf(	"tcp_set_send_timer: conn[%d] setting timer to %ld ms (+%ld ms)\n",		tcp_conn-tcp_conn_table,		(curr_time+rtt)*1000/HZ, rtt*1000/HZ));	/* Start the timer */	clck_timer(&tcp_conn->tc_transmit_timer,		curr_time+rtt, tcp_send_timeout, tcp_conn-tcp_conn_table);	tcp_conn->tc_stt= curr_time;}/*tcp_close_connection*/PUBLIC void tcp_close_connection(tcp_conn, error)tcp_conn_t *tcp_conn;int error;{	int i;	tcp_port_t *tcp_port;	tcp_fd_t *tcp_fd;	tcp_conn_t *tc;	assert (tcp_check_conn(tcp_conn) ||		(tcp_print_conn(tcp_conn), printf("\n"), 0));	assert (tcp_conn->tc_flags & TCF_INUSE);	tcp_conn->tc_error= error;	tcp_port= tcp_conn->tc_port;	tcp_fd= tcp_conn->tc_fd;	if (tcp_conn->tc_state == TCS_CLOSED)		return;	tcp_conn->tc_state= TCS_CLOSED;	DBLOCK(0x10, tcp_print_state(tcp_conn); printf("\n"));	if (tcp_fd && (tcp_fd->tf_flags & TFF_LISTENQ))	{		for (i= 0; i<TFL_LISTEN_MAX; i++)		{			if (tcp_fd->tf_listenq[i] == tcp_conn)				break;		}		assert(i < TFL_LISTEN_MAX);		tcp_fd->tf_listenq[i]= NULL;		assert(tcp_conn->tc_connInprogress);		tcp_conn->tc_connInprogress= 0;		tcp_conn->tc_fd= NULL;		tcp_fd= NULL;	}	else if (tcp_fd)	{		tcp_conn->tc_busy++;		assert(tcp_fd->tf_conn == tcp_conn);		if (tcp_fd->tf_flags & TFF_READ_IP)			tcp_fd_read (tcp_conn, 1);		assert (!(tcp_fd->tf_flags & TFF_READ_IP));		if (tcp_fd->tf_flags & TFF_SEL_READ)			tcp_rsel_read (tcp_conn);		if (tcp_fd->tf_flags & TFF_WRITE_IP)		{			tcp_fd_write(tcp_conn);			tcp_conn_write(tcp_conn, 1);		}		assert (!(tcp_fd->tf_flags & TFF_WRITE_IP));		if (tcp_fd->tf_flags & TFF_IOCTL_IP)		{			tcp_fd_write(tcp_conn);			tcp_conn_write(tcp_conn, 1);		}		if (tcp_fd->tf_flags & TFF_IOCTL_IP)			assert(tcp_fd->tf_ioreq != NWIOTCPSHUTDOWN);		if (tcp_fd->tf_flags & TFF_SEL_WRITE) 			tcp_rsel_write(tcp_conn);		if (tcp_conn->tc_connInprogress)			tcp_restart_connect(tcp_conn);		assert (!tcp_conn->tc_connInprogress);		assert (!(tcp_fd->tf_flags & TFF_IOCTL_IP) ||			(printf("req= 0x%lx\n",			(unsigned long)tcp_fd->tf_ioreq), 0));		tcp_conn->tc_busy--;	}	if (tcp_conn->tc_rcvd_data)	{		bf_afree(tcp_conn->tc_rcvd_data);		tcp_conn->tc_rcvd_data= NULL;	}	tcp_conn->tc_flags &= ~TCF_FIN_RECV;	tcp_conn->tc_RCV_LO= tcp_conn->tc_RCV_NXT;	if (tcp_conn->tc_adv_data)	{		bf_afree(tcp_conn->tc_adv_data);		tcp_conn->tc_adv_data= NULL;	}	if (tcp_conn->tc_send_data)	{		bf_afree(tcp_conn->tc_send_data);		tcp_conn->tc_send_data= NULL;		tcp_conn->tc_SND_TRM=			tcp_conn->tc_SND_NXT= tcp_conn->tc_SND_UNA;	}	tcp_conn->tc_SND_TRM= tcp_conn->tc_SND_NXT= tcp_conn->tc_SND_UNA;	if (tcp_conn->tc_remipopt)	{		bf_afree(tcp_conn->tc_remipopt);		tcp_conn->tc_remipopt= NULL;	}	if (tcp_conn->tc_tcpopt)	{		bf_afree(tcp_conn->tc_tcpopt);		tcp_conn->tc_tcpopt= NULL;	}	if (tcp_conn->tc_frag2send)	{		bf_afree(tcp_conn->tc_frag2send);		tcp_conn->tc_frag2send= NULL;	}	if (tcp_conn->tc_flags & TCF_MORE2WRITE)	{		for (tc= tcp_port->tp_snd_head; tc; tc= tc->tc_send_link)		{			if (tc->tc_send_link == tcp_conn)				break;		}		if (tc == NULL)		{			assert(tcp_port->tp_snd_head == tcp_conn);			tcp_port->tp_snd_head= tcp_conn->tc_send_link;		}		else		{			tc->tc_send_link= tcp_conn->tc_send_link;			if (tc->tc_send_link == NULL)				tcp_port->tp_snd_tail= tc;		}		tcp_conn->tc_flags &= ~TCF_MORE2WRITE;	}	clck_untimer (&tcp_conn->tc_transmit_timer);	tcp_conn->tc_transmit_seq= 0;					/* clear all flags but TCF_INUSE */	tcp_conn->tc_flags &= TCF_INUSE;	assert (tcp_check_conn(tcp_conn));}/* * $PchId: tcp_send.c,v 1.32 2005/06/28 14:21:52 philip Exp $ */

⌨️ 快捷键说明

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