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

📄 tcp.c

📁 minix3的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		listen_conn->tc_ISS= best_conn->tc_ISS;		if (best_conn->tc_senddis > listen_conn->tc_senddis)			listen_conn->tc_senddis= best_conn->tc_senddis;		return listen_conn;	}	assert (listen_conn);	return listen_conn;}/*new_conn_for_queue*/PRIVATE tcp_conn_t *new_conn_for_queue(tcp_fd)tcp_fd_t *tcp_fd;{	int i;	tcp_conn_t *tcp_conn;	assert(tcp_fd->tf_flags & TFF_LISTENQ);	for (i= 0; i<TFL_LISTEN_MAX; i++)	{		if (tcp_fd->tf_listenq[i] == NULL)			break;	}	if (i >= TFL_LISTEN_MAX)		return NULL;	tcp_conn= find_empty_conn();	if (!tcp_conn)		return NULL;	tcp_fd->tf_listenq[i]= tcp_conn;	(void)tcp_su4listen(tcp_fd, tcp_conn, 0 /* !do_listenq */);	return tcp_conn;}/*maybe_listen*/PRIVATE int maybe_listen(locaddr, locport, remaddr, remport)ipaddr_t locaddr;tcpport_t locport;ipaddr_t remaddr;tcpport_t remport;{	int i;	tcp_conn_t *tcp_conn;	tcp_fd_t *fd;	for (i= tcp_conf_nr, tcp_conn= tcp_conn_table+i;		i<TCP_CONN_NR; i++, tcp_conn++)	{		if (!(tcp_conn->tc_flags & TCF_INUSE))			continue;		if (tcp_conn->tc_locaddr != locaddr)		{			continue;		}		if (tcp_conn->tc_locport != locport )		{			continue;		}		if (!tcp_conn->tc_orglisten)			continue;		fd= tcp_conn->tc_fd;		if (!fd)			continue;		if ((fd->tf_tcpconf.nwtc_flags & NWTC_SET_RP) &&			tcp_conn->tc_remport != remport)		{			continue;		}		if ((fd->tf_tcpconf.nwtc_flags & NWTC_SET_RA) &&			tcp_conn->tc_remaddr != remaddr)		{			continue;		}		if (!(fd->tf_flags & TFF_DEL_RST))			continue;		return 1;	}	return 0;}PUBLIC void tcp_reply_ioctl(tcp_fd, reply)tcp_fd_t *tcp_fd;int reply;{	assert (tcp_fd->tf_flags & TFF_IOCTL_IP);	assert (tcp_fd->tf_ioreq == NWIOTCPSHUTDOWN ||		tcp_fd->tf_ioreq == NWIOTCPLISTEN ||		tcp_fd->tf_ioreq == NWIOTCPLISTENQ ||		tcp_fd->tf_ioreq == NWIOTCPACCEPTTO ||		tcp_fd->tf_ioreq == NWIOTCPCONN);		tcp_fd->tf_flags &= ~TFF_IOCTL_IP;	reply_thr_get (tcp_fd, reply, TRUE);}PUBLIC void tcp_reply_write(tcp_fd, reply)tcp_fd_t *tcp_fd;size_t reply;{	assert (tcp_fd->tf_flags & TFF_WRITE_IP);	tcp_fd->tf_flags &= ~TFF_WRITE_IP;	reply_thr_get (tcp_fd, reply, FALSE);}PUBLIC void tcp_reply_read(tcp_fd, reply)tcp_fd_t *tcp_fd;size_t reply;{	assert (tcp_fd->tf_flags & TFF_READ_IP);	tcp_fd->tf_flags &= ~TFF_READ_IP;	reply_thr_put (tcp_fd, reply, FALSE);}PUBLIC int tcp_write(fd, count)int fd;size_t count;{	tcp_fd_t *tcp_fd;	tcp_conn_t *tcp_conn;	tcp_fd= &tcp_fd_table[fd];	assert (tcp_fd->tf_flags & TFF_INUSE);	if (!(tcp_fd->tf_flags & TFF_CONNECTEDx))	{		reply_thr_get (tcp_fd, ENOTCONN, FALSE);		return NW_OK;	}	tcp_conn= tcp_fd->tf_conn;	if (tcp_conn->tc_state == TCS_CLOSED)	{		reply_thr_get(tcp_fd, tcp_conn->tc_error, FALSE);		return NW_OK;	}	if (tcp_conn->tc_flags & TCF_FIN_SENT)	{		reply_thr_get (tcp_fd, ESHUTDOWN, FALSE);		return NW_OK;	}	tcp_fd->tf_flags |= TFF_WRITE_IP;	tcp_fd->tf_write_offset= 0;	tcp_fd->tf_write_count= count;	/* New data may cause a segment to be sent. Clear PUSH_NOW	 * from last NWIOTCPPUSH ioctl.	 */	tcp_conn->tc_flags &= ~(TCF_NO_PUSH|TCF_PUSH_NOW);	/* Start the timer (if necessary) */	if (tcp_conn->tc_SND_TRM == tcp_conn->tc_SND_UNA)		tcp_set_send_timer(tcp_conn);	assert(tcp_conn->tc_busy == 0);	tcp_conn->tc_busy++;	tcp_fd_write(tcp_conn);	tcp_conn->tc_busy--;	tcp_conn_write(tcp_conn, 0);	if (!(tcp_fd->tf_flags & TFF_WRITE_IP))		return NW_OK;	else		return NW_SUSPEND;}PUBLIC inttcp_read(fd, count)int fd;size_t count;{	tcp_fd_t *tcp_fd;	tcp_conn_t *tcp_conn;	tcp_fd= &tcp_fd_table[fd];	assert (tcp_fd->tf_flags & TFF_INUSE);	if (!(tcp_fd->tf_flags & TFF_CONNECTEDx))	{		reply_thr_put (tcp_fd, ENOTCONN, FALSE);		return NW_OK;	}	tcp_conn= tcp_fd->tf_conn;	tcp_fd->tf_flags |= TFF_READ_IP;	tcp_fd->tf_read_offset= 0;	tcp_fd->tf_read_count= count;	assert(tcp_conn->tc_busy == 0);	tcp_conn->tc_busy++;	tcp_fd_read(tcp_conn, 0);	tcp_conn->tc_busy--;	if (!(tcp_fd->tf_flags & TFF_READ_IP))		return NW_OK;	else		return NW_SUSPEND;}/*tcp_restart_connectreply the success or failure of a connect to the user.*/PUBLIC void tcp_restart_connect(tcp_conn)tcp_conn_t *tcp_conn;{	tcp_fd_t *tcp_fd;	int reply;	assert(tcp_conn->tc_connInprogress);	tcp_conn->tc_connInprogress= 0;	tcp_fd= tcp_conn->tc_fd;	assert(tcp_fd);	if (tcp_fd->tf_flags & TFF_LISTENQ)	{		/* Special code for listen queues */		assert(tcp_conn->tc_state != TCS_CLOSED);		/* Reply for select */		if ((tcp_fd->tf_flags & TFF_SEL_READ) &&			tcp_fd->tf_select_res)		{			tcp_fd->tf_flags &= ~TFF_SEL_READ;			tcp_fd->tf_select_res(tcp_fd->tf_srfd,				SR_SELECT_READ);		}		/* Reply for acceptto */		if (tcp_fd->tf_flags & TFF_IOCTL_IP)			(void) tcp_acceptto(tcp_fd);		return;	}	if (tcp_conn->tc_state == TCS_CLOSED)	{		reply= tcp_conn->tc_error;		assert(tcp_conn->tc_fd == tcp_fd);		tcp_fd->tf_conn= NULL;		tcp_conn->tc_fd= NULL;	}	else	{		tcp_fd->tf_flags |= TFF_CONNECTEDx;		reply= NW_OK;	}	if (tcp_fd->tf_flags & TFF_CONNECTING)	{		/* Special code for asynchronous connects */		tcp_fd->tf_flags &= ~TFF_CONNECTING;		/* Reply for select */		if ((tcp_fd->tf_flags & TFF_SEL_WRITE) &&			tcp_fd->tf_select_res)		{			tcp_fd->tf_flags &= ~TFF_SEL_WRITE;			tcp_fd->tf_select_res(tcp_fd->tf_srfd,				SR_SELECT_WRITE);		}		return;	}	assert(tcp_fd->tf_flags & TFF_IOCTL_IP);	assert(tcp_fd->tf_ioreq == NWIOTCPLISTEN ||		tcp_fd->tf_ioreq == NWIOTCPCONN);	tcp_reply_ioctl (tcp_fd, reply);}/*tcp_close*/PUBLIC void tcp_close(fd)int fd;{	int i;	tcp_fd_t *tcp_fd;	tcp_conn_t *tcp_conn;	tcp_fd= &tcp_fd_table[fd];	assert (tcp_fd->tf_flags & TFF_INUSE);	assert (!(tcp_fd->tf_flags &		(TFF_IOCTL_IP|TFF_READ_IP|TFF_WRITE_IP)));	if (tcp_fd->tf_flags & TFF_LISTENQ)	{		/* Special code for listen queues */		for (i= 0; i<TFL_LISTEN_MAX; i++)		{			tcp_conn= tcp_fd->tf_listenq[i];			if (!tcp_conn)				continue;			tcp_fd->tf_listenq[i]= NULL;			assert(tcp_conn->tc_fd == tcp_fd);			tcp_conn->tc_fd= NULL;			if (tcp_conn->tc_connInprogress)			{				tcp_conn->tc_connInprogress= 0;				tcp_close_connection(tcp_conn, ENOCONN);				continue;			}			tcp_shutdown (tcp_conn);			if (tcp_conn->tc_state == TCS_ESTABLISHED)				tcp_conn->tc_state= TCS_CLOSING;			/* Set the retransmission timeout a bit smaller. */			tcp_conn->tc_rt_dead= TCP_DEF_RT_MAX_CLOSING;			/* If all data has been acknowledged, close the connection. */			if (tcp_conn->tc_SND_UNA == tcp_conn->tc_SND_NXT)				tcp_close_connection(tcp_conn, ENOTCONN);		}		tcp_conn= tcp_fd->tf_conn;		assert(tcp_conn->tc_fd == tcp_fd);		assert (tcp_conn->tc_connInprogress);		tcp_conn->tc_connInprogress= 0;		tcp_conn->tc_fd= NULL;		tcp_fd->tf_conn= NULL;		tcp_close_connection(tcp_conn, ENOCONN);	}	for (i= 0; i<TFL_LISTEN_MAX; i++)	{		assert(tcp_fd->tf_listenq[i] == NULL);	}	if (tcp_fd->tf_flags & TFF_CONNECTING)	{		tcp_conn= tcp_fd->tf_conn;		assert(tcp_conn != NULL);		assert (tcp_conn->tc_connInprogress);		tcp_conn->tc_connInprogress= 0;		tcp_conn->tc_fd= NULL;		tcp_fd->tf_conn= NULL;		tcp_close_connection(tcp_conn, ENOCONN);		tcp_fd->tf_flags &= ~TFF_CONNECTING;	}	tcp_fd->tf_flags &= ~TFF_INUSE;	if (!tcp_fd->tf_conn)		return;	tcp_conn= tcp_fd->tf_conn;	assert(tcp_conn->tc_fd == tcp_fd);	tcp_conn->tc_fd= NULL;	assert (!tcp_conn->tc_connInprogress);	tcp_shutdown (tcp_conn);	if (tcp_conn->tc_state == TCS_ESTABLISHED)	{		tcp_conn->tc_state= TCS_CLOSING;	}	/* Set the retransmission timeout a bit smaller. */	tcp_conn->tc_rt_dead= TCP_DEF_RT_MAX_CLOSING;	/* If all data has been acknowledged, close the connection. */	if (tcp_conn->tc_SND_UNA == tcp_conn->tc_SND_NXT)		tcp_close_connection(tcp_conn, ENOTCONN);}PUBLIC int tcp_cancel(fd, which_operation)int fd;int which_operation;{	tcp_fd_t *tcp_fd;	tcp_conn_t *tcp_conn;	tcp_fd= &tcp_fd_table[fd];	assert (tcp_fd->tf_flags & TFF_INUSE);	tcp_conn= tcp_fd->tf_conn;	switch (which_operation)	{	case SR_CANCEL_WRITE:		assert (tcp_fd->tf_flags & TFF_WRITE_IP);		tcp_fd->tf_flags &= ~TFF_WRITE_IP;		if (tcp_fd->tf_write_offset)			reply_thr_get (tcp_fd, tcp_fd->tf_write_offset, FALSE);		else			reply_thr_get (tcp_fd, EINTR, FALSE);		break;	case SR_CANCEL_READ:		assert (tcp_fd->tf_flags & TFF_READ_IP);		tcp_fd->tf_flags &= ~TFF_READ_IP;		if (tcp_fd->tf_read_offset)			reply_thr_put (tcp_fd, tcp_fd->tf_read_offset, 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;		switch (tcp_fd->tf_ioreq)		{		case NWIOGTCPCONF:			reply_thr_put (tcp_fd, EINTR, TRUE);			break;		case NWIOSTCPCONF:		case NWIOTCPSHUTDOWN:			reply_thr_get (tcp_fd, EINTR, TRUE);			break;		case NWIOTCPCONN:		case NWIOTCPLISTEN:			assert (tcp_conn->tc_connInprogress);			tcp_conn->tc_connInprogress= 0;			tcp_conn->tc_fd= NULL;			tcp_fd->tf_conn= NULL;			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;	nwio_tcpcl_t *tcpcl;	long nwtcl_flags;	int r, do_asynch;	acc_t *data;	if (!(tcp_fd->tf_flags & TFF_CONF_SET))	{		tcp_reply_ioctl(tcp_fd, EBADMODE);		return NW_OK;	}	assert (!(tcp_fd->tf_flags & TFF_CONNECTEDx) &&		!(tcp_fd->tf_flags & TFF_CONNECTING) &&		!(tcp_fd->tf_flags & TFF_LISTENQ));	if ((tcp_fd->tf_tcpconf.nwtc_flags & (NWTC_SET_RA|NWTC_SET_RP))		!= (NWTC_SET_RA|NWTC_SET_RP))	{		tcp_reply_ioctl(tcp_fd, EBADMODE);		return NW_OK;	}	data= (*tcp_fd->tf_get_userdata) (tcp_fd->tf_srfd, 0,		sizeof(*tcpcl), TRUE);	if (!data)		return EFAULT;	data= bf_packIffLess(data, sizeof(*tcpcl));	assert (data->acc_length == sizeof(*tcpcl));	tcpcl= (nwio_tcpcl_t *)ptr2acc_data(data);	nwtcl_flags= tcpcl->nwtcl_flags;	bf_afree(data); data= NULL; tcpcl= NULL;	if (nwtcl_flags == TCF_ASYNCH)		do_asynch= 1;	else if (nwtcl_flags == TCF_DEFAULT)		do_asynch= 0;	else	{		tcp_reply_ioctl(tcp_fd, EINVAL);		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_fd)		{			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;	r= tcp_su4connect(tcp_fd);	if (r == NW_SUSPEND && do_asynch)	{		tcp_fd->tf_flags |= TFF_CONNECTING;		tcp_reply_ioctl(tcp_fd, EINPROGRESS);		r= NW_OK;	}	return r;}

⌨️ 快捷键说明

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