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

📄 tcp.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
ipaddr_t remaddr;{	tcp_conn_t *tcp_conn;	int i, state;#if DEBUG & 256 { where(); printf("find_conn_entry(locport= %u, locaddr= ", ntohs(locport)); 	writeIpAddr(locaddr);	printf("\nremport= %u, remaddr= ", ntohs(remport));	writeIpAddr(remaddr); printf(")\n"); }#endifassert(remport);assert(remaddr);	for (i=TCP_PORT_NR, tcp_conn= tcp_conn_table+i; i<TCP_CONN_NR;		i++, tcp_conn++)		/* the first TCP_PORT_NR connection are reserved for			RSTs */	{		if (tcp_conn->tc_flags == TCF_EMPTY)			continue;		if (tcp_conn->tc_locport != locport ||			tcp_conn->tc_locaddr != locaddr ||			tcp_conn->tc_remport != remport ||			tcp_conn->tc_remaddr != remaddr)			continue;		if (tcp_conn->tc_mainuser)			return tcp_conn;		state= tcp_conn->tc_state;		if (state != TCS_CLOSED)		{			tcp_close_connection(tcp_conn, ENOCONN);		}		return tcp_conn;	}	return NULL;}PRIVATE void read_ip_packets(tcp_port)tcp_port_t *tcp_port;{	int result;	do	{		tcp_port->tp_flags |= TPF_READ_IP;#if DEBUG & 256 { where(); printf("doing ip_read\n"); }#endif		result= ip_read(tcp_port->tp_ipfd, TCP_MAX_DATAGRAM);		if (result == NW_SUSPEND)		{			tcp_port->tp_flags |= TPF_READ_SP;			return;		}assert(result == NW_OK);		tcp_port->tp_flags &= ~TPF_READ_IP;	} while(!(tcp_port->tp_flags & TPF_READ_IP));}/*process_inc_fragm*/PRIVATE void process_inc_fragm(tcp_port, data)tcp_port_t *tcp_port;acc_t *data;{	acc_t *ip_pack, *tcp_pack;	ip_hdr_t *ip_hdr;	tcp_hdr_t *tcp_hdr;	tcp_conn_t *tcp_conn;	int pack_len, ip_hdr_len;	pack_len= bf_bufsize(data);	if ((u16_t)~tcp_pack_oneCsum(data, pack_len))	{		data= bf_packIffLess(data, IP_MIN_HDR_SIZE);		ip_hdr= (ip_hdr_t *)ptr2acc_data(data);#if DEBUG { where(); printf("checksum error in tcp_pack\n");   printf("tcp_pack_oneCsum(...)= 0x%x (%d) length= %d\n",     (u16_t)~tcp_pack_oneCsum(data, pack_len),    (u16_t)~tcp_pack_oneCsum(data, pack_len), pack_len);    printf("src ip_addr= "); writeIpAddr(ip_hdr->ih_src); printf("\n"); }#endif		bf_afree(data);		return;	}	data= bf_packIffLess(data, IP_MIN_HDR_SIZE);	ip_hdr= (ip_hdr_t *)ptr2acc_data(data);	ip_hdr_len= (ip_hdr->ih_vers_ihl & IH_IHL_MASK) << 2;	ip_pack= bf_cut(data, 0, ip_hdr_len);	pack_len -= ip_hdr_len;	tcp_pack= bf_cut(data, ip_hdr_len, pack_len);	bf_afree(data);	tcp_pack= bf_packIffLess(tcp_pack, TCP_MIN_HDR_SIZE);	tcp_hdr= (tcp_hdr_t *)ptr2acc_data(tcp_pack);	tcp_conn= find_best_conn(ip_hdr, tcp_hdr);assert(tcp_conn);#if DEBUG & 256 { where(); tcp_print_pack(ip_hdr, tcp_hdr); printf("\n");   tcp_print_conn(tcp_conn); printf("\n"); }#endif	tcp_hdr->th_chksum= pack_len;	/* tcp_pack size in chksum field */#if DEBUG & 256 { where(); printf("calling tcp_frag2conn(...)\n"); }#endif	tcp_frag2conn(tcp_conn, ip_pack, tcp_pack);}/*find_best_conn*/PRIVATE tcp_conn_t *find_best_conn(ip_hdr, tcp_hdr)ip_hdr_t *ip_hdr;tcp_hdr_t *tcp_hdr;{		int best_level, new_level;	tcp_conn_t *best_conn, *listen_conn, *tcp_conn;	tcp_fd_t *tcp_fd;	int i;	ipaddr_t locaddr;	ipaddr_t remaddr;	tcpport_t locport;	tcpport_t remport;	locaddr= ip_hdr->ih_dst;	remaddr= ip_hdr->ih_src;	locport= tcp_hdr->th_dstport;	remport= tcp_hdr->th_srcport;	if (!remport)	/* This can interfere with a listen, so we reject it			 * by clearing the requested port 			 */		locport= 0;		#if DEBUG & 256 { where(); printf("find_best_conn(locport= %u, locaddr= ",	ntohs(locport)); writeIpAddr(locaddr);	printf("\nremport= %u, remaddr= ", ntohs(remport));	writeIpAddr(remaddr); printf(")\n"); }#endif	best_level= 0;	best_conn= NULL;	listen_conn= NULL;	for (i= TCP_PORT_NR, tcp_conn= tcp_conn_table+i;		i<TCP_CONN_NR; i++, tcp_conn++)		/* the first TCP_PORT_NR connection are reserved for			RSTs */	{		if (!(tcp_conn->tc_flags & TCF_INUSE))			continue;		/* First fast check for open connections. */		if (tcp_conn->tc_locaddr == locaddr && 			tcp_conn->tc_locport == locport &&			tcp_conn->tc_remport == remport &&			tcp_conn->tc_remaddr == remaddr &&			tcp_conn->tc_mainuser)			return tcp_conn;		/* Now check for listens and abandoned connections. */		if (tcp_conn->tc_locaddr != locaddr)		{#if DEBUG { where(); printf("conn %d: wrong locaddr\n",i); }#endif			continue;		}		new_level= 0;		if (tcp_conn->tc_locport)		{			if (locport != tcp_conn->tc_locport)			{#if DEBUG & 256 { where(); printf("conn %d: wrong locport(%u)\n",i,	ntohs(tcp_conn->tc_locport)); }#endif				continue;			}			new_level += 4;		}		if (tcp_conn->tc_remport)		{			if (remport != tcp_conn->tc_remport)			{#if DEBUG & 256 { where(); printf("conn %d: wrong remport\n",i); }#endif				continue;			}			new_level += 1;		}		if (tcp_conn->tc_remaddr)		{			if (remaddr != tcp_conn->tc_remaddr)			{#if DEBUG & 256 { where(); printf("conn %d: wrong remaddr\n",i); }#endif				continue;			}			new_level += 2;		}		if (new_level<best_level)			continue;		if (new_level != 7 && tcp_conn->tc_state != TCS_LISTEN)			continue;		if (new_level == 7 && !tcp_conn->tc_mainuser)			/* We found an abandoned connection */		{assert (!best_conn);			best_conn= tcp_conn;			continue;		}		if (!(tcp_hdr->th_flags & THF_SYN))			continue;		best_level= new_level;		listen_conn= tcp_conn;	}	if (!best_conn && !listen_conn)	{#if DEBUG & 256 { where(); printf("refusing connection for locport= %u, locaddr= ",	ntohs(locport)); writeIpAddr(locaddr);	printf("\nremport= %u, remaddr= ", ntohs(remport));	writeIpAddr(remaddr); printf("\n"); }#endif		for (i=0, tcp_conn= tcp_conn_table; i<TCP_PORT_NR;			i++, tcp_conn++)			/* find valid port to send RST */			if ((tcp_conn->tc_flags & TCF_INUSE) &&				tcp_conn->tc_locaddr==locaddr)			{				break;			}assert (tcp_conn);assert (tcp_conn->tc_state == TCS_CLOSED);		tcp_conn->tc_locport= locport;		tcp_conn->tc_locaddr= locaddr;		tcp_conn->tc_remport= remport;		tcp_conn->tc_remaddr= remaddr;assert (!tcp_conn->tc_mainuser);assert (!tcp_conn->tc_readuser);assert (!tcp_conn->tc_writeuser);		return tcp_conn;	}	if (best_conn)	{assert(!best_conn->tc_mainuser);		if (!listen_conn)			return best_conn;		tcp_fd= listen_conn->tc_mainuser;assert(tcp_fd && tcp_fd == listen_conn->tc_connuser &&	tcp_fd->tf_conn == listen_conn);		if (best_conn->tc_state != TCS_CLOSED)			tcp_close_connection(best_conn, ENOCONN);		best_conn->tc_state= TCS_LISTEN;#if DEBUG { where(); tcp_write_state(best_conn); }#endif		best_conn->tc_mainuser= best_conn->tc_connuser=			tcp_fd;		best_conn->tc_flags= listen_conn->tc_flags;		tcp_fd->tf_conn= best_conn;		listen_conn->tc_flags= TCF_EMPTY;#if DEBUG & 16 { where(); printf("tcp_conn_table[%d].tc_flags= 0x%x\n", 	listen_conn-tcp_conn_table, listen_conn->tc_flags); }#endif		return best_conn;	}assert (listen_conn);	return listen_conn;}PUBLIC void tcp_reply_ioctl(tcp_fd, reply)tcp_fd_t *tcp_fd;int reply;{#if DEBUG & 256 { where(); printf("tcp_reply_ioctl called\n"); }#endif#if DEBUG if (!(tcp_fd->tf_flags & TFF_IOCTL_IP)) { where(); printf("not TFF_IOCTL_IP\n"); }#endifassert (tcp_fd->tf_flags & TFF_IOCTL_IP);#if DEBUGif (tcp_fd->tf_ioreq != NWIOTCPSHUTDOWN && tcp_fd->tf_ioreq != NWIOTCPLISTEN &&	tcp_fd->tf_ioreq != NWIOTCPCONN) { where(); printf("wrong value in ioreq (0x%lx)\n", tcp_fd->tf_ioreq); }#endifassert (tcp_fd->tf_ioreq == NWIOTCPSHUTDOWN ||	tcp_fd->tf_ioreq == NWIOTCPLISTEN || 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);#if DEBUG & 256 { where(); printf("tcp_reply_read(.., %d)\n", reply); }#endif	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_CONNECTED))	{		reply_thr_get (tcp_fd, ENOTCONN, FALSE);		return NW_OK;	}	tcp_conn= tcp_fd->tf_conn;	if (tcp_conn->tc_flags & TCF_FIN_SENT)	{#if DEBUG & 16 { where(); printf("replying ESHUTDOWN for connection %d and fd %d\n",	tcp_conn-tcp_conn_table, tcp_fd-tcp_fd_table); }#endif		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;	if (tcp_conn->tc_writeuser)		return NW_SUSPEND;	tcp_conn->tc_writeuser= tcp_fd;	tcp_restart_fd_write (tcp_conn);	if (!(tcp_fd->tf_flags & TFF_WRITE_IP))		return NW_OK;	else		return NW_SUSPEND;}PUBLIC int tcp_read(fd, count)int fd;size_t count;{	tcp_fd_t *tcp_fd;	tcp_conn_t *tcp_conn;#if DEBUG & 256 { where(); printf("tcp_read(%d, %u)\n", fd, count); }#endif	tcp_fd= &tcp_fd_table[fd];	assert (tcp_fd->tf_flags & TFF_INUSE);	if (!(tcp_fd->tf_flags & TFF_CONNECTED))	{		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;	if (tcp_conn->tc_readuser)		return NW_SUSPEND;	tcp_conn->tc_readuser= tcp_fd;	tcp_restart_fd_read (tcp_conn);	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_fd)tcp_fd_t *tcp_fd;{	tcp_conn_t *tcp_conn;	int reply;#if DEBUG & 256 { where(); printf("tcp_restart_connect called\n"); }#endifassert (tcp_fd->tf_flags & TFF_IOCTL_IP);assert (tcp_fd->tf_ioreq == NWIOTCPLISTEN || tcp_fd->tf_ioreq == NWIOTCPCONN);	tcp_conn= tcp_fd->tf_conn;assert (tcp_conn->tc_connuser == tcp_fd);	if (tcp_conn->tc_state == TCS_CLOSED)		reply= tcp_conn->tc_error;	else	{		tcp_fd->tf_flags |= TFF_CONNECTED;		reply= NW_OK;	}	tcp_conn->tc_connuser= 0;#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_reply_ioctl (tcp_fd, reply);}PUBLIC void tcp_close(fd)int fd;{	tcp_fd_t *tcp_fd;	tcp_conn_t *tcp_conn;	tcp_fd= &tcp_fd_table[fd];#if DEBUG { if (!(tcp_fd->tf_flags & TFF_INUSE)) { where(); printf("not inuse\n"); }   if (tcp_fd->tf_flags & TFF_IOCTL_IP) { where(); printf("ioctl ip\n"); }   if (tcp_fd->tf_flags & TFF_READ_IP) { where(); printf("read ip\n"); }   if (tcp_fd->tf_flags & TFF_WRITE_IP) { where(); printf("write ip\n"); } }#endifassert (tcp_fd->tf_flags & TFF_INUSE);assert (!(tcp_fd->tf_flags & (TFF_IOCTL_IP|TFF_READ_IP|TFF_WRITE_IP)));	tcp_fd->tf_flags &= ~TFF_INUSE;	if (!tcp_fd->tf_conn)		return;	tcp_conn= tcp_fd->tf_conn;	close_mainuser(tcp_conn, tcp_fd);	tcp_shutdown (tcp_conn);}PUBLIC int tcp_cancel(fd, which_operation)int fd;int which_operation;{	tcp_fd_t *tcp_fd;	tcp_conn_t *tcp_conn;	int i;	int type;#if DEBUG & 256 { where(); printf("tcp_cancel(%d, %d)\n", fd, which_operation); }#endif	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_conn->tc_writeuser == tcp_fd)		{			tcp_conn->tc_writeuser= 0;			tcp_restart_fd_write (tcp_conn);		}		if (tcp_fd->tf_write_count)			reply_thr_get (tcp_fd, tcp_fd->tf_write_count, FALSE);		else			reply_thr_get (tcp_fd, EINTR, FALSE);

⌨️ 快捷键说明

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