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

📄 tcp.c

📁 minix3的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
				i<TCP_CONN_NR; i++, tcp_conn++)			{				if (!(tcp_conn->tc_flags & TCF_INUSE))					continue;				if (tcp_conn->tc_port != tcp_port)					continue;				tcp_conn->tc_locaddr= ipaddr;			}		}		else			DBLOCK(1, printf("tcp_put_pkt: no TCP header\n"));		bf_afree(data);		return;	}	data->acc_linkC++;	ip_pack= data;	ip_pack= bf_align(ip_pack, ip_hdr_len, 4);	ip_hdr= (ip_hdr_t *)ptr2acc_data(ip_pack);	data= bf_delhead(data, ip_hdr_len);	/* Compute the checksum */	sum= tcp_pack_oneCsum(ip_hdr, data);	/* Extract the TCP header */	if (ip_datalen < TCP_MIN_HDR_SIZE)	{		DBLOCK(1, printf("truncated TCP header\n"));		bf_afree(ip_pack);		bf_afree(data);		return;	}	data= bf_packIffLess(data, TCP_MIN_HDR_SIZE);	tcp_hdr= (tcp_hdr_t *)ptr2acc_data(data);	tcp_hdr_len= (tcp_hdr->th_data_off & TH_DO_MASK) >> 2;		/* actualy (>> 4) << 2 */	if (ip_datalen < tcp_hdr_len || tcp_hdr_len < TCP_MIN_HDR_SIZE)	{		if (tcp_hdr_len < TCP_MIN_HDR_SIZE)		{			DBLOCK(1, printf("strange tcp header length %d\n",				tcp_hdr_len));		}		else		{			DBLOCK(1, printf("truncated TCP header\n"));		}		bf_afree(ip_pack);		bf_afree(data);		return;	}	data->acc_linkC++;	tcp_pack= data;	tcp_pack= bf_align(tcp_pack, tcp_hdr_len, 4);	tcp_hdr= (tcp_hdr_t *)ptr2acc_data(tcp_pack);	if (ip_datalen == tcp_hdr_len)	{		bf_afree(data);		data= NULL;	}	else		data= bf_delhead(data, tcp_hdr_len);	tcp_datalen= ip_datalen-tcp_hdr_len;	if ((u16_t)~sum)	{		DBLOCK(1, printf("checksum error in tcp packet\n");			printf("tcp_pack_oneCsum(...)= 0x%x length= %d\n", 			(u16_t)~sum, tcp_datalen);			printf("src ip_addr= "); writeIpAddr(ip_hdr->ih_src);			printf("\n"));		bf_afree(ip_pack);		bf_afree(tcp_pack);		bf_afree(data);		return;	}	srcaddr= ip_hdr->ih_src;	dstaddr= ip_hdr->ih_dst;	srcport= tcp_hdr->th_srcport;	dstport= tcp_hdr->th_dstport;	bits= srcaddr ^ dstaddr ^ srcport ^ dstport;	bits= (bits >> 16) ^ bits;	bits= (bits >> 8) ^ bits;	hash= ((bits >> TCP_CONN_HASH_SHIFT) ^ bits) & (TCP_CONN_HASH_NR-1);	conn_p= tcp_port->tp_conn_hash[hash];	if (conn_p[0]->tc_locport == dstport &&		conn_p[0]->tc_remport == srcport &&		conn_p[0]->tc_remaddr == srcaddr &&		conn_p[0]->tc_locaddr == dstaddr)	{		tcp_conn= conn_p[0];	}	else if (conn_p[1]->tc_locport == dstport &&		conn_p[1]->tc_remport == srcport &&		conn_p[1]->tc_remaddr == srcaddr &&		conn_p[1]->tc_locaddr == dstaddr)	{		tcp_conn= conn_p[1];		conn_p[1]= conn_p[0];		conn_p[0]= tcp_conn;	}	else if (conn_p[2]->tc_locport == dstport &&		conn_p[2]->tc_remport == srcport &&		conn_p[2]->tc_remaddr == srcaddr &&		conn_p[2]->tc_locaddr == dstaddr)	{		tcp_conn= conn_p[2];		conn_p[2]= conn_p[1];		conn_p[1]= conn_p[0];		conn_p[0]= tcp_conn;	}	else if (conn_p[3]->tc_locport == dstport &&		conn_p[3]->tc_remport == srcport &&		conn_p[3]->tc_remaddr == srcaddr &&		conn_p[3]->tc_locaddr == dstaddr)	{		tcp_conn= conn_p[3];		conn_p[3]= conn_p[2];		conn_p[2]= conn_p[1];		conn_p[1]= conn_p[0];		conn_p[0]= tcp_conn;	}	else		tcp_conn= NULL;	if ((tcp_conn != NULL && tcp_conn->tc_state == TCS_CLOSED) ||		(tcp_hdr->th_flags & THF_SYN))	{		tcp_conn= NULL;	}	if (tcp_conn == NULL)	{		tcp_conn= find_best_conn(ip_hdr, tcp_hdr);		if (!tcp_conn)		{			/* listen backlog hack */			bf_afree(ip_pack);			bf_afree(tcp_pack);			bf_afree(data);			return;		}		if (tcp_conn->tc_state != TCS_CLOSED)		{			conn_p[3]= conn_p[2];			conn_p[2]= conn_p[1];			conn_p[1]= conn_p[0];			conn_p[0]= tcp_conn;		}	}	assert(tcp_conn->tc_busy == 0);	tcp_conn->tc_busy++;	tcp_frag2conn(tcp_conn, ip_hdr, tcp_hdr, data, tcp_datalen);	tcp_conn->tc_busy--;	bf_afree(ip_pack);	bf_afree(tcp_pack);}PUBLIC int tcp_open (port, srfd, get_userdata, put_userdata, put_pkt,	select_res)int port;int srfd;get_userdata_t get_userdata;put_userdata_t put_userdata;put_pkt_t put_pkt;select_res_t select_res;{	int i, j;	tcp_fd_t *tcp_fd;	for (i=0; i<TCP_FD_NR && (tcp_fd_table[i].tf_flags & TFF_INUSE);		i++);	if (i>=TCP_FD_NR)	{		return EAGAIN;	}	tcp_fd= &tcp_fd_table[i];	tcp_fd->tf_flags= TFF_INUSE;	tcp_fd->tf_flags |= TFF_PUSH_DATA;	tcp_fd->tf_port= &tcp_port_table[port];	tcp_fd->tf_srfd= srfd;	tcp_fd->tf_tcpconf.nwtc_flags= TCP_DEF_CONF;	tcp_fd->tf_tcpconf.nwtc_remaddr= 0;	tcp_fd->tf_tcpconf.nwtc_remport= 0;	tcp_fd->tf_tcpopt.nwto_flags= TCP_DEF_OPT;	tcp_fd->tf_get_userdata= get_userdata;	tcp_fd->tf_put_userdata= put_userdata;	tcp_fd->tf_select_res= select_res;	tcp_fd->tf_conn= 0;	for (j= 0; j<TFL_LISTEN_MAX; j++)		tcp_fd->tf_listenq[j]= NULL;	return i;}/*tcp_ioctl*/PUBLIC int tcp_ioctl (fd, req)int fd;ioreq_t req;{	tcp_fd_t *tcp_fd;	tcp_port_t *tcp_port;	tcp_conn_t *tcp_conn;	nwio_tcpconf_t *tcp_conf;	nwio_tcpopt_t *tcp_opt;	tcp_cookie_t *cookiep;	acc_t *acc, *conf_acc, *opt_acc;	int result, *bytesp;	u8_t rndbits[RAND256_BUFSIZE];	tcp_fd= &tcp_fd_table[fd];	assert (tcp_fd->tf_flags & TFF_INUSE);	tcp_port= tcp_fd->tf_port;	tcp_fd->tf_flags |= TFF_IOCTL_IP;	tcp_fd->tf_ioreq= req;	if (tcp_port->tp_state != TPS_MAIN)	{		tcp_fd->tf_flags |= TFF_IOC_INIT_SP;		return NW_SUSPEND;	}	switch (req)	{	case NWIOSTCPCONF:		if ((tcp_fd->tf_flags & TFF_CONNECTEDx) ||			(tcp_fd->tf_flags & TFF_CONNECTING) ||			(tcp_fd->tf_flags & TFF_LISTENQ))		{			tcp_fd->tf_flags &= ~TFF_IOCTL_IP;			reply_thr_get (tcp_fd, EISCONN, TRUE);			result= NW_OK;			break;		}		result= tcp_setconf(tcp_fd);		break;	case NWIOGTCPCONF:		conf_acc= bf_memreq(sizeof(*tcp_conf));assert (conf_acc->acc_length == sizeof(*tcp_conf));		tcp_conf= (nwio_tcpconf_t *)ptr2acc_data(conf_acc);		*tcp_conf= tcp_fd->tf_tcpconf;		if (tcp_fd->tf_flags & TFF_CONNECTEDx)		{			tcp_conn= tcp_fd->tf_conn;			tcp_conf->nwtc_locport= tcp_conn->tc_locport;			tcp_conf->nwtc_remaddr= tcp_conn->tc_remaddr;			tcp_conf->nwtc_remport= tcp_conn->tc_remport;		}		tcp_conf->nwtc_locaddr= tcp_fd->tf_port->tp_ipaddr;		result= (*tcp_fd->tf_put_userdata)(tcp_fd->tf_srfd,			0, conf_acc, TRUE);		tcp_fd->tf_flags &= ~TFF_IOCTL_IP;		reply_thr_put(tcp_fd, result, TRUE);		result= NW_OK;		break;	case NWIOSTCPOPT:		result= tcp_setopt(tcp_fd);		break;	case NWIOGTCPOPT:		opt_acc= bf_memreq(sizeof(*tcp_opt));		assert (opt_acc->acc_length == sizeof(*tcp_opt));		tcp_opt= (nwio_tcpopt_t *)ptr2acc_data(opt_acc);		*tcp_opt= tcp_fd->tf_tcpopt;		result= (*tcp_fd->tf_put_userdata)(tcp_fd->tf_srfd,			0, opt_acc, TRUE);		tcp_fd->tf_flags &= ~TFF_IOCTL_IP;		reply_thr_put(tcp_fd, result, TRUE);		result= NW_OK;		break;	case NWIOTCPCONN:		if (tcp_fd->tf_flags & TFF_CONNECTING)		{			tcp_fd->tf_flags &= ~TFF_IOCTL_IP;			reply_thr_get (tcp_fd, EALREADY, TRUE);			result= NW_OK;			break;		}		if (tcp_fd->tf_flags & TFF_CONNECTEDx)		{			tcp_fd->tf_flags &= ~TFF_IOCTL_IP;			reply_thr_get (tcp_fd, EISCONN, TRUE);			result= NW_OK;			break;		}		result= tcp_connect(tcp_fd);		if (result == NW_OK)			tcp_fd->tf_flags &= ~TFF_IOCTL_IP;		break;	case NWIOTCPLISTEN:	case NWIOTCPLISTENQ:		if ((tcp_fd->tf_flags & TFF_CONNECTEDx) ||			(tcp_fd->tf_flags & TFF_LISTENQ) ||			(tcp_fd->tf_flags & TFF_CONNECTING))		{			tcp_fd->tf_flags &= ~TFF_IOCTL_IP;			reply_thr_get (tcp_fd, EISCONN, TRUE);			result= NW_OK;			break;		}		result= tcp_listen(tcp_fd, (req == NWIOTCPLISTENQ));		break;	case NWIOTCPSHUTDOWN:		if (!(tcp_fd->tf_flags & TFF_CONNECTEDx))		{			tcp_fd->tf_flags &= ~TFF_IOCTL_IP;			reply_thr_get (tcp_fd, ENOTCONN, TRUE);			result= NW_OK;			break;		}		tcp_fd->tf_flags |= TFF_IOCTL_IP;		tcp_fd->tf_ioreq= req;		tcp_conn= tcp_fd->tf_conn;		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_IOCTL_IP))			result= NW_OK;		else			result= NW_SUSPEND;		break;	case NWIOTCPPUSH:		if (!(tcp_fd->tf_flags & TFF_CONNECTEDx))		{			tcp_fd->tf_flags &= ~TFF_IOCTL_IP;			reply_thr_get (tcp_fd, ENOTCONN, TRUE);			result= NW_OK;			break;		}		tcp_conn= tcp_fd->tf_conn;		tcp_conn->tc_SND_PSH= tcp_conn->tc_SND_NXT;		tcp_conn->tc_flags &= ~TCF_NO_PUSH;		tcp_conn->tc_flags |= 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);		tcp_conn_write(tcp_conn, 0);		tcp_fd->tf_flags &= ~TFF_IOCTL_IP;		reply_thr_get (tcp_fd, NW_OK, TRUE);		result= NW_OK;		break;	case NWIOGTCPCOOKIE:		if (!(tcp_fd->tf_flags & TFF_COOKIE))		{			tcp_fd->tf_cookie.tc_ref= fd;			rand256(rndbits);			assert(sizeof(tcp_fd->tf_cookie.tc_secret) <=				RAND256_BUFSIZE);			memcpy(tcp_fd->tf_cookie.tc_secret, 				rndbits, sizeof(tcp_fd->tf_cookie.tc_secret));			tcp_fd->tf_flags |= TFF_COOKIE;		}		acc= bf_memreq(sizeof(*cookiep));		cookiep= (tcp_cookie_t *)ptr2acc_data(acc);		*cookiep= tcp_fd->tf_cookie;		result= (*tcp_fd->tf_put_userdata)(tcp_fd->tf_srfd,			0, acc, TRUE);		tcp_fd->tf_flags &= ~TFF_IOCTL_IP;		reply_thr_put(tcp_fd, result, TRUE);		result= NW_OK;		break;	case NWIOTCPACCEPTTO:		result= tcp_acceptto(tcp_fd);		break;	case FIONREAD:		acc= bf_memreq(sizeof(*bytesp));		bytesp= (int *)ptr2acc_data(acc);		tcp_bytesavailable(tcp_fd, bytesp);		result= (*tcp_fd->tf_put_userdata)(tcp_fd->tf_srfd,			0, acc, TRUE);		tcp_fd->tf_flags &= ~TFF_IOCTL_IP;		reply_thr_put(tcp_fd, result, TRUE);		result= NW_OK;		break;	default:		tcp_fd->tf_flags &= ~TFF_IOCTL_IP;		reply_thr_get(tcp_fd, EBADIOCTL, TRUE);		result= NW_OK;		break;	}	return result;}/*tcp_setconf*/PRIVATE int tcp_setconf(tcp_fd)tcp_fd_t *tcp_fd;{	nwio_tcpconf_t *tcpconf;	nwio_tcpconf_t oldconf, newconf;	acc_t *data;	tcp_fd_t *fd_ptr;	unsigned int new_en_flags, new_di_flags,		old_en_flags, old_di_flags, all_flags, flags;	int i;	data= (*tcp_fd->tf_get_userdata)		(tcp_fd->tf_srfd, 0,		sizeof(nwio_tcpconf_t), TRUE);	if (!data)		return EFAULT;	data= bf_packIffLess(data, sizeof(nwio_tcpconf_t));assert (data->acc_length == sizeof(nwio_tcpconf_t));	tcpconf= (nwio_tcpconf_t *)ptr2acc_data(data);	oldconf= tcp_fd->tf_tcpconf;	newconf= *tcpconf;	old_en_flags= oldconf.nwtc_flags & 0xffff;	old_di_flags= (oldconf.nwtc_flags >> 16) &		0xffff;	new_en_flags= newconf.nwtc_flags & 0xffff;	new_di_flags= (newconf.nwtc_flags >> 16) &		0xffff;	if (new_en_flags & new_di_flags)	{		tcp_fd->tf_flags &= ~TFF_IOCTL_IP;		reply_thr_get(tcp_fd, EBADMODE, TRUE);		bf_afree(data);		return NW_OK;	}	/* NWTC_ACC_MASK */	if (new_di_flags & NWTC_ACC_MASK)	{		tcp_fd->tf_flags &= ~TFF_IOCTL_IP;		reply_thr_get(tcp_fd, EBADMODE, TRUE);		bf_afree(data);		return NW_OK;		/* access modes can't be disabled */	}	if (!(new_en_flags & NWTC_ACC_MASK))		new_en_flags |= (old_en_flags & NWTC_ACC_MASK);		/* NWTC_LOCPORT_MASK */	if (new_di_flags & NWTC_LOCPORT_MASK)	{		tcp_fd->tf_flags &= ~TFF_IOCTL_IP;		reply_thr_get(tcp_fd, EBADMODE, TRUE);		bf_afree(data);		return NW_OK;		/* the loc ports can't be disabled */	}	if (!(new_en_flags & NWTC_LOCPORT_MASK))	{		new_en_flags |= (old_en_flags &			NWTC_LOCPORT_MASK);		newconf.nwtc_locport= oldconf.nwtc_locport;	}	else if ((new_en_flags & NWTC_LOCPORT_MASK) == NWTC_LP_SEL)	{		newconf.nwtc_locport= find_unused_port(tcp_fd-			tcp_fd_table);	}	else if ((new_en_flags & NWTC_LOCPORT_MASK) == NWTC_LP_SET)	{		if (!newconf.nwtc_locport)		{			tcp_fd->tf_flags &= ~TFF_IOCTL_IP;			reply_thr_get(tcp_fd, EBADMODE, TRUE);			bf_afree(data);			return NW_OK;		}	}		/* NWTC_REMADDR_MASK */	if (!((new_en_flags | new_di_flags) &		NWTC_REMADDR_MASK))	{		new_en_flags |= (old_en_flags &			NWTC_REMADDR_MASK);		new_di_flags |= (old_di_flags &			NWTC_REMADDR_MASK);		newconf.nwtc_remaddr= oldconf.nwtc_remaddr;	}	else if (new_en_flags & NWTC_SET_RA)	{		if (!newconf.nwtc_remaddr)		{			tcp_fd->tf_flags &= ~TFF_IOCTL_IP;			reply_thr_get(tcp_fd, EBADMODE, TRUE);			bf_afree(data);			return NW_OK;		}	}	else	{assert (new_di_flags & NWTC_REMADDR_MASK);		newconf.nwtc_remaddr= 0;	}	/* NWTC_REMPORT_MASK */	if (!((new_en_flags | new_di_flags) & NWTC_REMPORT_MASK))	{		new_en_flags |= (old_en_flags &			NWTC_REMPORT_MASK);		new_di_flags |= (old_di_flags &			NWTC_REMPORT_MASK);		newconf.nwtc_remport=			oldconf.nwtc_remport;	}	else if (new_en_flags & NWTC_SET_RP)	{		if (!newconf.nwtc_remport)		{			tcp_fd->tf_flags &= ~TFF_IOCTL_IP;			reply_thr_get(tcp_fd, EBADMODE, TRUE);			bf_afree(data);			return NW_OK;		}	}	else	{assert (new_di_flags & NWTC_REMPORT_MASK);		newconf.nwtc_remport= 0;	}

⌨️ 快捷键说明

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