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

📄 tcp.c

📁 minix3的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*tcp_su4connect*/PRIVATE int tcp_su4connect(tcp_fd)tcp_fd_t *tcp_fd;{	tcp_conn_t *tcp_conn;	tcp_conn= tcp_fd->tf_conn;	tcp_conn->tc_locport= tcp_fd->tf_tcpconf.nwtc_locport;	tcp_conn->tc_locaddr= tcp_fd->tf_port->tp_ipaddr;	assert (tcp_fd->tf_tcpconf.nwtc_flags & NWTC_SET_RP);	assert (tcp_fd->tf_tcpconf.nwtc_flags & NWTC_SET_RA);	tcp_conn->tc_remport= tcp_fd->tf_tcpconf.nwtc_remport;	tcp_conn->tc_remaddr= tcp_fd->tf_tcpconf.nwtc_remaddr;	tcp_setup_conn(tcp_fd->tf_port, tcp_conn);	tcp_conn->tc_fd= tcp_fd;	tcp_conn->tc_connInprogress= 1;	tcp_conn->tc_orglisten= FALSE;	tcp_conn->tc_state= TCS_SYN_SENT;	tcp_conn->tc_rt_dead= TCP_DEF_RT_MAX_CONNECT;	/* Start the timer (if necessary) */	tcp_set_send_timer(tcp_conn);	tcp_conn_write(tcp_conn, 0);	if (tcp_conn->tc_connInprogress)		return NW_SUSPEND;	else		return NW_OK;}/*tcp_listen*/PRIVATE int tcp_listen(tcp_fd, do_listenq)tcp_fd_t *tcp_fd;int do_listenq;{	tcp_conn_t *tcp_conn;	if (!(tcp_fd->tf_flags & TFF_CONF_SET))	{		tcp_fd->tf_flags &= ~TFF_IOCTL_IP;		reply_thr_get(tcp_fd, EBADMODE, TRUE);		return NW_OK;	}	assert (!(tcp_fd->tf_flags & TFF_CONNECTEDx) &&		!(tcp_fd->tf_flags & TFF_CONNECTING) &&		!(tcp_fd->tf_flags & TFF_LISTENQ));	tcp_conn= tcp_fd->tf_conn;	assert(!tcp_conn);	if ((tcp_fd->tf_tcpconf.nwtc_flags & (NWTC_SET_RA|NWTC_SET_RP))		== (NWTC_SET_RA|NWTC_SET_RP))	{		tcp_conn= find_conn_entry(			tcp_fd->tf_tcpconf.nwtc_locport,			tcp_fd->tf_port->tp_ipaddr,			tcp_fd->tf_tcpconf.nwtc_remport,			tcp_fd->tf_tcpconf.nwtc_remaddr);		if (tcp_conn)		{			if (tcp_conn->tc_fd)			{				tcp_fd->tf_flags &= ~TFF_IOCTL_IP;				reply_thr_get (tcp_fd, EADDRINUSE, TRUE);				return NW_OK;			}			tcp_fd->tf_conn= tcp_conn;			return tcp_su4listen(tcp_fd, tcp_conn, do_listenq);		}	}	tcp_conn= find_empty_conn();	if (!tcp_conn)	{		tcp_fd->tf_flags &= ~TFF_IOCTL_IP;		reply_thr_get (tcp_fd, EAGAIN, TRUE);		return NW_OK;	}	tcp_fd->tf_conn= tcp_conn;	return tcp_su4listen(tcp_fd, tcp_conn, do_listenq);}/*tcp_acceptto*/PRIVATE int tcp_acceptto(tcp_fd)tcp_fd_t *tcp_fd;{	int i, dst_nr;	tcp_fd_t *dst_fd;	tcp_conn_t *tcp_conn;	tcp_cookie_t *cookiep;	acc_t *data;	if (!(tcp_fd->tf_flags & TFF_LISTENQ))	{		tcp_reply_ioctl(tcp_fd, EINVAL);		return NW_OK;	}	for (i= 0; i<TFL_LISTEN_MAX; i++)	{		tcp_conn= tcp_fd->tf_listenq[i];		if (tcp_conn && !tcp_conn->tc_connInprogress)			break;	}	if (i >= TFL_LISTEN_MAX)	{		/* Nothing, suspend caller */		return NW_SUSPEND;	}	data= (*tcp_fd->tf_get_userdata) (tcp_fd->tf_srfd, 0,		sizeof(*cookiep), TRUE);	if (!data)		return EFAULT;	data= bf_packIffLess(data, sizeof(*cookiep));	cookiep= (tcp_cookie_t *)ptr2acc_data(data);	dst_nr= cookiep->tc_ref;	if (dst_nr < 0 || dst_nr >= TCP_FD_NR)	{		printf("tcp_acceptto: bad fd %d\n", dst_nr);		tcp_reply_ioctl(tcp_fd, EINVAL);		return NW_OK;	}	dst_fd= &tcp_fd_table[dst_nr];	if (!(dst_fd->tf_flags & TFF_INUSE) ||		(dst_fd->tf_flags & (TFF_READ_IP|TFF_WRITE_IP|TFF_IOCTL_IP)) ||		dst_fd->tf_conn != NULL ||		!(dst_fd->tf_flags & TFF_COOKIE))	{		printf("tcp_acceptto: bad flags 0x%x or conn %p for fd %d\n",			dst_fd->tf_flags, dst_fd->tf_conn, dst_nr);		tcp_reply_ioctl(tcp_fd, EINVAL);		return NW_OK;	}	if (memcmp(cookiep, &dst_fd->tf_cookie, sizeof(*cookiep)) != 0)	{		printf("tcp_acceptto: bad cookie\n");		return NW_OK;	}	/* Move connection */	tcp_fd->tf_listenq[i]= NULL;	tcp_conn->tc_fd= dst_fd;	dst_fd->tf_conn= tcp_conn;	dst_fd->tf_flags |= TFF_CONNECTEDx;	tcp_reply_ioctl(tcp_fd, NW_OK);	return NW_OK;}PRIVATE void tcp_buffree (priority)int priority;{	int i;	tcp_conn_t *tcp_conn;	if (priority == TCP_PRI_FRAG2SEND)	{		for (i=0, tcp_conn= tcp_conn_table; i<TCP_CONN_NR; i++,			tcp_conn++)		{			if (!(tcp_conn->tc_flags & TCF_INUSE))				continue;			if (!tcp_conn->tc_frag2send)				continue;			if (tcp_conn->tc_busy)				continue;			bf_afree(tcp_conn->tc_frag2send);			tcp_conn->tc_frag2send= 0;		}	}	if (priority == TCP_PRI_CONN_EXTRA)	{		for (i=0, tcp_conn= tcp_conn_table; i<TCP_CONN_NR; i++,			tcp_conn++)		{			if (!(tcp_conn->tc_flags & TCF_INUSE))				continue;			if (tcp_conn->tc_busy)				continue;			if (tcp_conn->tc_adv_data)			{				bf_afree(tcp_conn->tc_adv_data);				tcp_conn->tc_adv_data= NULL;			}		}	}	if (priority == TCP_PRI_CONNwoUSER)	{		for (i=0, tcp_conn= tcp_conn_table; i<TCP_CONN_NR; i++,			tcp_conn++)		{			if (!(tcp_conn->tc_flags & TCF_INUSE))				continue;			if (tcp_conn->tc_busy)				continue;			if (tcp_conn->tc_fd)				continue;			if (tcp_conn->tc_state == TCS_CLOSED)				continue;			if (tcp_conn->tc_rcvd_data == NULL &&				tcp_conn->tc_send_data == NULL)			{				continue;			}			tcp_close_connection (tcp_conn, EOUTOFBUFS);		}	}	if (priority == TCP_PRI_CONN_INUSE)	{		for (i=0, tcp_conn= tcp_conn_table; i<TCP_CONN_NR; i++,			tcp_conn++)		{			if (!(tcp_conn->tc_flags & TCF_INUSE))				continue;			if (tcp_conn->tc_busy)				continue;			if (tcp_conn->tc_state == TCS_CLOSED)				continue;			if (tcp_conn->tc_rcvd_data == NULL &&				tcp_conn->tc_send_data == NULL)			{				continue;			}			tcp_close_connection (tcp_conn, EOUTOFBUFS);		}	}}#ifdef BUF_CONSISTENCY_CHECKPRIVATE void tcp_bufcheck(){	int i;	tcp_conn_t *tcp_conn;	tcp_port_t *tcp_port;	for (i= 0, tcp_port= tcp_port_table; i<tcp_conf_nr; i++, tcp_port++)	{		if (tcp_port->tp_pack)			bf_check_acc(tcp_port->tp_pack);	}	for (i= 0, tcp_conn= tcp_conn_table; i<TCP_CONN_NR; i++, tcp_conn++)	{		assert(!tcp_conn->tc_busy);		if (tcp_conn->tc_rcvd_data)			bf_check_acc(tcp_conn->tc_rcvd_data);		if (tcp_conn->tc_adv_data)			bf_check_acc(tcp_conn->tc_adv_data);		if (tcp_conn->tc_send_data)			bf_check_acc(tcp_conn->tc_send_data);		if (tcp_conn->tc_remipopt)			bf_check_acc(tcp_conn->tc_remipopt);		if (tcp_conn->tc_tcpopt)			bf_check_acc(tcp_conn->tc_tcpopt);		if (tcp_conn->tc_frag2send)			bf_check_acc(tcp_conn->tc_frag2send);	}}#endifPUBLIC void tcp_notreach(tcp_conn)tcp_conn_t *tcp_conn;{	int new_ttl;	new_ttl= tcp_conn->tc_ttl;	if (new_ttl == IP_MAX_TTL)	{		if (tcp_conn->tc_state == TCS_SYN_SENT)			tcp_close_connection(tcp_conn, EDSTNOTRCH);		return;	}	else if (new_ttl < TCP_DEF_TTL_NEXT)		new_ttl= TCP_DEF_TTL_NEXT;	else	{		new_ttl *= 2;		if (new_ttl> IP_MAX_TTL)			new_ttl= IP_MAX_TTL;	}	tcp_conn->tc_ttl= new_ttl;	tcp_conn->tc_stt= 0;	tcp_conn->tc_SND_TRM= tcp_conn->tc_SND_UNA;	tcp_conn_write(tcp_conn, 1);}FORWARD u32_t mtu_table[]={	/* From RFC-1191 *//*	Plateau    MTU    Comments                      Reference	*//*	------     ---    --------                      ---------	*//*		  65535  Official maximum MTU          RFC 791		*//*		  65535  Hyperchannel                  RFC 1044		*/	65535,	32000,    /*     Just in case					*//*		  17914  16Mb IBM Token Ring           ref. [6]		*/	17914,/*		  8166   IEEE 802.4                    RFC 1042		*/	8166,/*		  4464   IEEE 802.5 (4Mb max)          RFC 1042		*//*		  4352   FDDI (Revised)                RFC 1188		*/	4352, /* (1%) *//*		  2048   Wideband Network              RFC 907		*//*		  2002   IEEE 802.5 (4Mb recommended)  RFC 1042		*/	2002, /* (2%) *//*		  1536   Exp. Ethernet Nets            RFC 895		*//*		  1500   Ethernet Networks             RFC 894		*//*		  1500   Point-to-Point (default)      RFC 1134		*//*		  1492   IEEE 802.3                    RFC 1042		*/	1492, /* (3%) *//*		  1006   SLIP                          RFC 1055		*//*		  1006   ARPANET                       BBN 1822		*/	1006,/*		  576    X.25 Networks                 RFC 877		*//*		  544    DEC IP Portal                 ref. [10]	*//*		  512    NETBIOS                       RFC 1088		*//*		  508    IEEE 802/Source-Rt Bridge     RFC 1042		*//*		  508    ARCNET                        RFC 1051		*/	508, /* (13%) *//*		  296    Point-to-Point (low delay)    RFC 1144		*/	296,	68,       /*     Official minimum MTU          RFC 791		*/	0,        /*     End of list					*/};PUBLIC void tcp_mtu_exceeded(tcp_conn)tcp_conn_t *tcp_conn;{	u16_t mtu;	int i;	clock_t curr_time;	if (!(tcp_conn->tc_flags & TCF_PMTU))	{		/* Strange, got MTU exceeded but DF is not set. Ignore		 * the error. If the problem persists, the connection will		 * time-out.		 */		return;	}	curr_time= get_time();	/* We get here in cases. Either were are trying to find an MTU 	 * that works at all, or we are trying see how far we can increase	 * the current MTU. If the last change to the MTU was a long time 	 * ago, we assume the second case. 	 */	if (curr_time >= tcp_conn->tc_mtutim + TCP_PMTU_INCR_IV)	{		mtu= tcp_conn->tc_mtu;		mtu -= mtu/TCP_PMTU_INCR_FRAC;		tcp_conn->tc_mtu= mtu;		tcp_conn->tc_mtutim= curr_time;		DBLOCK(1, printf(			"tcp_mtu_exceeded: new (lowered) mtu %d for conn %d\n",			mtu, tcp_conn-tcp_conn_table));		tcp_conn->tc_stt= 0;		tcp_conn->tc_SND_TRM= tcp_conn->tc_SND_UNA;		tcp_conn_write(tcp_conn, 1);		return;	}	tcp_conn->tc_mtutim= curr_time;	mtu= tcp_conn->tc_mtu;	for (i= 0; mtu_table[i] >= mtu; i++)		;	/* Nothing to do */	mtu= mtu_table[i];	if (mtu >= TCP_MIN_PATH_MTU)	{		tcp_conn->tc_mtu= mtu;	}	else	{		/* Small MTUs can be used for denial-of-service attacks.		 * Switch-off PMTU if the MTU becomes too small.		 */		tcp_conn->tc_flags &= ~TCF_PMTU;		tcp_conn->tc_mtu= TCP_MIN_PATH_MTU;		DBLOCK(1, printf(			"tcp_mtu_exceeded: clearing TCF_PMTU for conn %d\n",			tcp_conn-tcp_conn_table););	}	DBLOCK(1, printf("tcp_mtu_exceeded: new mtu %d for conn %d\n",		mtu, tcp_conn-tcp_conn_table););	tcp_conn->tc_stt= 0;	tcp_conn->tc_SND_TRM= tcp_conn->tc_SND_UNA;	tcp_conn_write(tcp_conn, 1);}PUBLIC void tcp_mtu_incr(tcp_conn)tcp_conn_t *tcp_conn;{	clock_t curr_time;	u32_t mtu;	assert(tcp_conn->tc_mtu < tcp_conn->tc_max_mtu);	if (!(tcp_conn->tc_flags & TCF_PMTU))	{		/* Use a much longer time-out for retrying PMTU discovery		 * after is has been disabled. Note that PMTU discovery		 * can be disabled during a short loss of connectivity.		 */		curr_time= get_time();		if (curr_time > tcp_conn->tc_mtutim+TCP_PMTU_EN_IV)		{			tcp_conn->tc_flags |= TCF_PMTU;			DBLOCK(1, printf(				"tcp_mtu_incr: setting TCF_PMTU for conn %d\n",				tcp_conn-tcp_conn_table););		}		return;	}	mtu= tcp_conn->tc_mtu;	mtu += mtu/TCP_PMTU_INCR_FRAC;	if (mtu > tcp_conn->tc_max_mtu)		mtu= tcp_conn->tc_max_mtu;	tcp_conn->tc_mtu= mtu;	DBLOCK(0x1, printf("tcp_mtu_incr: new mtu %ld for conn %d\n",		mtu, tcp_conn-tcp_conn_table););}/*tcp_setup_conn*/PRIVATE void tcp_setup_conn(tcp_port, tcp_conn)tcp_port_t *tcp_port;tcp_conn_t *tcp_conn;{	u16_t mss;	assert(!tcp_conn->tc_connInprogress);	tcp_conn->tc_port= tcp_port;	if (tcp_conn->tc_flags & TCF_INUSE)	{		assert (tcp_conn->tc_state == TCS_CLOSED);		assert (!tcp_conn->tc_send_data);		if (tcp_conn->tc_senddis < get_time())			tcp_conn->tc_ISS= 0;	}	else	{		assert(!tcp_conn->tc_busy);		tcp_conn->tc_senddis= 0;		tcp_conn->tc_ISS= 0;		tcp_conn->tc_tos= TCP_DEF_TOS;		tcp_conn->tc_ttl= TCP_DEF_TTL;		tcp_conn->tc_rcv_wnd= TCP_MAX_RCV_WND_SIZE;		tcp_conn->tc_fd= NULL;	}	if (!tcp_conn->tc_ISS)	{		tcp_conn->tc_ISS= tcp_rand32();	}	tcp_conn->tc_SND_UNA= tcp_conn->tc_ISS;	tcp_conn->tc_SND_TRM= tcp_conn->tc_ISS;	tcp_conn->tc_SND_NXT= tcp_conn->tc_ISS+1;	tcp_conn->tc_SND_UP= tcp_conn->tc_ISS;	tcp_conn->tc_SND_PSH= tcp_conn->tc_ISS+1;	tcp_conn->tc_IRS= 0;	tcp_conn->tc_RCV_LO= tcp_conn->tc_IRS;	tcp_conn->tc_RCV_NXT= tcp_conn->tc_IRS;	tcp_conn->tc_RCV_HI= tcp_conn->tc_IRS;	tcp_conn->tc_RCV_UP= tcp_conn->tc_IRS;	assert(tcp_conn->tc_rcvd_data == NULL);	assert(tcp_conn->tc_adv_data == NULL);	assert(tcp_conn->tc_send_data == NULL);	tcp_conn->tc_ka_time= TCP_DEF_KEEPALIVE;	tcp_conn->tc_remipopt= NULL;	tcp_conn->tc_tcpopt= NULL;	assert(tcp_conn->tc_frag2send == NULL);	tcp_conn->tc_stt= 0;	tcp_conn->tc_rt_dead= TCP_DEF_RT_DEAD;	tcp_conn->tc_0wnd_to= 0;	tcp_conn->tc_artt= TCP_DEF_RTT*TCP_RTT_SCALE;	tcp_conn->tc_drtt= 0;	tcp_conn->tc_rtt= TCP_DEF_RTT;	tcp_conn->tc_max_mtu= tcp_conn->tc_port->tp_mtu;	tcp_conn->tc_mtu= tcp_conn->tc_max_mtu;	tcp_conn->tc_mtutim= 0;	tcp_conn->tc_error= NW_OK;	mss= tcp_conn->tc_mtu-IP_TCP_MIN_HDR_SIZE;	tcp_conn->tc_snd_cwnd= tcp_conn->tc_SND_UNA + 2*mss;	tcp_conn->tc_snd_cthresh= TCP_MAX_SND_WND_SIZE;	tcp_conn->tc_snd_cinc=		(long)TCP_DEF_MSS*TCP_DEF_MSS/TCP_MAX_SND_WND_SIZE+1;	tcp_conn->tc_snd_wnd= TCP_MAX_SND_WND_SIZE;	tcp_conn->tc_rt_time= 0;	tcp_conn->tc_rt_seq= 0;	tcp_conn->tc_rt_threshold= tcp_conn->tc_ISS;	tcp_conn->tc_flags= TCF_INUSE;	tcp_conn->tc_flags |= TCF_PMTU;	clck_untimer(&tcp_conn->tc_transmit_timer);	tcp_conn->tc_transmit_seq= 0;}PRIVATE u32_t tcp_rand32(){	u8_t bits[RAND256_BUFSIZE];	rand256(bits);	return bits[0] | (bits[1] << 8) | (bits[2] << 16) | (bits[3] << 24);}/* * $PchId: tcp.c,v 1.34 2005/06/28 14:20:27 philip Exp $ */

⌨️ 快捷键说明

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