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

📄 tcp.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
		break;	case SR_CANCEL_READ:assert (tcp_fd->tf_flags & TFF_READ_IP);		tcp_fd->tf_flags &= ~TFF_READ_IP;		if (tcp_conn->tc_readuser == tcp_fd)		{			tcp_conn->tc_readuser= 0;			tcp_restart_fd_read (tcp_conn);		}		if (tcp_fd->tf_read_count)			reply_thr_put (tcp_fd, tcp_fd->tf_read_count, FALSE);		else			reply_thr_put (tcp_fd, EINTR, FALSE);		break;	case SR_CANCEL_IOCTL:assert (tcp_fd->tf_flags & TFF_IOCTL_IP);		tcp_fd->tf_flags &= ~TFF_IOCTL_IP;		type= tcp_fd->tf_ioreq & IOCTYPE_MASK;		switch (type)		{		case NWIOGTCPCONF & IOCTYPE_MASK:			reply_thr_put (tcp_fd, EINTR, TRUE);			break;		case NWIOSTCPCONF & IOCTYPE_MASK:		case NWIOTCPSHUTDOWN & IOCTYPE_MASK:		case NWIOTCPATTACH & IOCTYPE_MASK:			reply_thr_get (tcp_fd, EINTR, TRUE);			break;		case NWIOTCPCONN & IOCTYPE_MASK:		case NWIOTCPLISTEN & IOCTYPE_MASK:assert (tcp_conn->tc_connuser == tcp_fd);			tcp_conn->tc_connuser= 0;			tcp_conn->tc_mainuser= 0;			tcp_close_connection(tcp_conn, ENOCONN);			reply_thr_get (tcp_fd, EINTR, TRUE);			break;		default:			ip_warning(( "unknown ioctl inprogress: 0x%x",				tcp_fd->tf_ioreq ));			reply_thr_get (tcp_fd, EINTR, TRUE);			break;		}		break;	default:		ip_panic(( "unknown cancel request" ));		break;	}	return NW_OK;}/*tcp_connect*/PRIVATE int tcp_connect(tcp_fd)tcp_fd_t *tcp_fd;{	tcp_conn_t *tcp_conn;	int state;	if (!(tcp_fd->tf_flags & TFF_OPTSET))	{#if DEBUG { where(); }#endif		tcp_reply_ioctl(tcp_fd, EBADMODE);		return NW_OK;	}	if (tcp_fd->tf_flags & TFF_CONNECT)	{		tcp_reply_ioctl(tcp_fd, EISCONN);		return NW_OK;	}	if ((tcp_fd->tf_tcpconf.nwtc_flags & (NWTC_SET_RA|NWTC_SET_RP))		!= (NWTC_SET_RA|NWTC_SET_RP))	{#if DEBUG { where(); printf("tcp_fd_table[%d].tf_tcpconf.nwtc_flags= 0x%x\n",	tcp_fd-tcp_fd_table, tcp_fd->tf_tcpconf.nwtc_flags); }#endif		tcp_reply_ioctl(tcp_fd, EBADMODE);		return NW_OK;	}assert(!tcp_fd->tf_conn);	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_mainuser)		{			tcp_reply_ioctl(tcp_fd, EADDRINUSE);			return NW_OK;		}	}	else	{		tcp_conn= find_empty_conn();		if (!tcp_conn)		{			tcp_reply_ioctl(tcp_fd, EAGAIN);			return NW_OK;		}	}	tcp_fd->tf_conn= tcp_conn;	return tcp_su4connect(tcp_fd);}/*tcp_su4connect*/PRIVATE int tcp_su4connect(tcp_fd)tcp_fd_t *tcp_fd;{	tcp_conn_t *tcp_conn;	acc_t *tmp_acc;	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_conn->tc_mainuser= tcp_fd;	tcp_setup_conn(tcp_conn);	tcp_conn->tc_port= tcp_fd->tf_port;	tcp_conn->tc_connuser= tcp_fd;#if DEBUG & 256 { where(); printf("tcp_conn_table[%d].tc_connuser= 0x%x\n", tcp_conn-	tcp_conn_table, tcp_conn->tc_connuser); }#endif	tcp_conn->tc_orglisten= FALSE;	tcp_conn->tc_state= TCS_SYN_SENT;#if DEBUG & 16 { where(); tcp_write_state(tcp_conn); }#endif	tcp_restart_write (tcp_conn);	if (tcp_conn->tc_connuser)		return NW_SUSPEND;	else		return NW_OK;}PRIVATE void close_mainuser(tcp_conn, tcp_fd)tcp_conn_t *tcp_conn;tcp_fd_t *tcp_fd;{	int i;	if (tcp_conn->tc_mainuser != tcp_fd)		return;	tcp_conn->tc_mainuser= 0;	assert (tcp_conn->tc_writeuser != tcp_fd);	assert (tcp_conn->tc_readuser != tcp_fd);	assert (tcp_conn->tc_connuser != tcp_fd);	for (i= 0, tcp_fd= tcp_fd_table; i<TCP_FD_NR; i++, tcp_fd++)	{		if (!(tcp_fd->tf_flags & TFF_INUSE))			continue;		if (tcp_fd->tf_conn != tcp_conn)			continue;		tcp_conn->tc_mainuser= tcp_fd;		return;	}}PRIVATE int conn_right4fd(tcp_conn, tcp_fd)tcp_fd_t *tcp_fd;tcp_conn_t *tcp_conn;{	unsigned long flags;	flags= tcp_fd->tf_tcpconf.nwtc_flags;	if (tcp_fd->tf_tcpconf.nwtc_locport != tcp_conn->tc_locport)		return FALSE;	if ((flags & NWTC_SET_RA) && tcp_fd->tf_tcpconf.nwtc_remaddr !=		tcp_conn->tc_remaddr)		return FALSE;	if ((flags & NWTC_SET_RP) && tcp_fd->tf_tcpconf.nwtc_remport !=		tcp_conn->tc_remport)		return FALSE;	if (tcp_fd->tf_port != tcp_conn->tc_port)		return FALSE;	return TRUE;}PRIVATE int tcp_attache(tcp_fd)tcp_fd_t *tcp_fd;{	tcp_conn_t *tcp_conn;	int state;	if (!(tcp_fd->tf_flags & TFF_OPTSET))	{		tcp_fd->tf_flags &= ~TFF_IOCTL_IP;		reply_thr_get(tcp_fd, EBADMODE, TRUE);		return NW_OK;	}	if (tcp_fd->tf_flags & TFF_CONNECT)	{		tcp_fd->tf_flags &= ~TFF_IOCTL_IP;		reply_thr_get(tcp_fd, EISCONN, TRUE);		return NW_OK;	}	if ((tcp_fd->tf_tcpconf.nwtc_flags & (NWTC_SET_RA|NWTC_SET_RP))		!= (NWTC_SET_RA|NWTC_SET_RP))	{		tcp_fd->tf_flags &= ~TFF_IOCTL_IP;		reply_thr_get(tcp_fd, EBADMODE, TRUE);		return NW_OK;	}	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 DEBUG { where(); printf("conn_entry not found\n"); }#endif		tcp_fd->tf_flags &= ~TFF_IOCTL_IP;		reply_thr_get (tcp_fd, ENOCONN, TRUE);		return NW_OK;	}	assert (tcp_conn->tc_flags & TCF_INUSE);	state= tcp_conn->tc_state;	if (state == TCS_CLOSED || state == TCS_LISTEN || state ==		TCS_SYN_SENT || state == TCS_SYN_RECEIVED)	{#if DEBUG { where(); printf("conn_entry in wrong state: ");	tcp_write_state(tcp_conn); printf("\n"); }#endif		tcp_fd->tf_flags &= ~TFF_IOCTL_IP;		reply_thr_get (tcp_fd, ENOCONN, TRUE);		return NW_OK;	}	tcp_fd->tf_conn= tcp_conn;	tcp_fd->tf_flags |= TFF_CONNECTED;	tcp_fd->tf_flags |= TFF_PUSH_DATA;	/* XXX */	return NW_OK;}/*tcp_listen*/PRIVATE int tcp_listen(tcp_fd)tcp_fd_t *tcp_fd;{	tcp_conn_t *tcp_conn;	int state;#if DEBUG & 256 { where(); printf("tcp_listen(&tcp_fd_table[%d]) called\n", tcp_fd-	tcp_fd_table); }#endif	if (!(tcp_fd->tf_flags & TFF_OPTSET))	{		tcp_fd->tf_flags &= ~TFF_IOCTL_IP;		reply_thr_get(tcp_fd, EBADMODE, TRUE);		return NW_OK;	}	if (tcp_fd->tf_flags & TFF_CONNECT)	{		tcp_fd->tf_flags &= ~TFF_IOCTL_IP;		reply_thr_get(tcp_fd, EISCONN, TRUE);		return NW_OK;	}	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_mainuser)			{				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= 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;#if DEBUG & 256 { where(); printf("tcp_conn_table[%d].tc_connuser= 0x%x\n", tcp_conn-	tcp_conn_table, tcp_conn->tc_connuser); }#endif	return tcp_su4listen(tcp_fd);}PRIVATE void tcp_buffree (priority, reqsize)int priority;size_t reqsize;{	int i;	tcp_conn_t *tcp_conn;	if (priority <TCP_PRI_FRAG2SEND)		return;#if DEBUG & 256 { where(); printf("tcp_buffree called\n"); }#endif	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;		bf_afree(tcp_conn->tc_frag2send);		tcp_conn->tc_frag2send= 0;		if (bf_free_buffsize >= reqsize)			return;	}	if (priority <TCP_PRI_CONNwoUSER)		return;	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_mainuser)			continue;		if (tcp_conn->tc_state == TCS_CLOSED)			continue;#if DEBUG { where(); printf("calling tcp_close_connection (out of memory)\n"); }#endif		tcp_close_connection (tcp_conn, EOUTOFBUFS);		if (bf_free_buffsize >= reqsize)			return;	}	if (priority <TCP_PRI_CONN_INUSE)		return;	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_state == TCS_CLOSED)			continue;#if DEBUG { where(); printf("calling tcp_close_connection (out of memory)\n"); }#endif		tcp_close_connection (tcp_conn, EOUTOFBUFS);		if (bf_free_buffsize >= reqsize)			return;	}}PRIVATE void tcp_notreach(pack)acc_t *pack;{	acc_t *tcp_pack;	ip_hdr_t *ip_hdr;	tcp_hdr_t *tcp_hdr;	tcp_conn_t *tcp_conn;	int ip_hdr_size;	int new_ttl;	pack->acc_linkC++;	pack= bf_packIffLess(pack, IP_MIN_HDR_SIZE);	ip_hdr= (ip_hdr_t *)ptr2acc_data(pack);	ip_hdr_size= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) << 2;	tcp_pack= bf_cut(pack, ip_hdr_size, TCP_MIN_HDR_SIZE);	tcp_pack= bf_packIffLess(tcp_pack, TCP_MIN_HDR_SIZE);	tcp_hdr= (tcp_hdr_t *)ptr2acc_data(tcp_pack);	tcp_conn= find_conn_entry( tcp_hdr->th_srcport, ip_hdr->ih_src,		tcp_hdr->th_dstport, ip_hdr->ih_dst);	if (tcp_conn)	{		new_ttl= tcp_conn->tc_ttl;		if (new_ttl == IP_MAX_TTL)		{#if DEBUG { where(); printf("calling tcp_close_connection\n"); }#endif			tcp_close_connection(tcp_conn, EDSTNOTRCH);			bf_afree(pack);			bf_afree(tcp_pack);			return;		}		new_ttl *= 2;		if (new_ttl> IP_MAX_TTL)			new_ttl= IP_MAX_TTL;		tcp_conn->tc_ttl= new_ttl;		tcp_conn->tc_no_retrans= 0;	}	else	{#if DEBUG { where(); printf("got a EDSTNOTRCH for non existing connection\n"); }#endif	}	bf_afree(pack);	bf_afree(tcp_pack);}/*tcp_setup_conn*/PRIVATE void tcp_setup_conn(tcp_conn)tcp_conn_t *tcp_conn;{assert(!tcp_conn->tc_readuser);assert(!tcp_conn->tc_writeuser);assert(!tcp_conn->tc_connuser);	if (tcp_conn->tc_flags & TCF_INUSE)	{assert (tcp_conn->tc_state == TCS_CLOSED || 	tcp_conn->tc_state == TCS_TIME_WAIT);assert (!tcp_conn->tc_send_data);		if (tcp_conn->tc_senddis < get_time())			tcp_conn->tc_ISS= 0;	}	else	{		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_WND_SIZE;		tcp_conn->tc_urg_wnd= TCP_DEF_URG_WND;	}	if (!tcp_conn->tc_ISS)	{		tcp_conn->tc_ISS= (get_time()/HZ)*ISS_INC_FREQ;	}	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;	tcp_conn->tc_SND_WL2= tcp_conn->tc_ISS;	tcp_conn->tc_IRS= 0;	tcp_conn->tc_SND_WL1= tcp_conn->tc_IRS;	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;	tcp_conn->tc_rcvd_data= 0;	tcp_conn->tc_rcv_queue= 0;	tcp_conn->tc_send_data= 0;	tcp_conn->tc_remipopt= 0;	tcp_conn->tc_remtcpopt= 0;	tcp_conn->tc_frag2send= 0;	tcp_conn->tc_no_retrans= 0;	tcp_conn->tc_max_no_retrans= TCP_DEF_MAX_NO_RETRANS;	tcp_conn->tc_0wnd_to= 0;	tcp_conn->tc_rtt= TCP_DEF_RTT;	tcp_conn->tc_ett= 0;	tcp_conn->tc_mss= TCP_DEF_MSS;	tcp_conn->tc_error= NW_OK;	tcp_conn->tc_snd_cwnd= tcp_conn->tc_SND_UNA + tcp_conn->tc_mss;	tcp_conn->tc_snd_cthresh= TCP_MAX_WND_SIZE;	tcp_conn->tc_snd_cinc= 0;	tcp_conn->tc_snd_wnd= TCP_MAX_WND_SIZE;	tcp_conn->tc_flags= TCF_INUSE;#if DEBUG & 256 { where(); printf("tcp_conn_table[%d].tc_flags= 0x%x\n", 	tcp_conn-tcp_conn_table, tcp_conn->tc_flags); }#endif}

⌨️ 快捷键说明

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