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

📄 udp.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
				*(udp_io_hdr_t *)ptr2acc_data(ipopt_pack)=					*udp_io_hdr;				udp_io_hdr= (udp_io_hdr_t *)					ptr2acc_data(ipopt_pack);				udp_io_hdr->uih_ip_opt_len= ip_hdr_size - 					IP_MIN_HDR_SIZE;				ipopt_pack->acc_next= bf_cut(ip_acc,					(size_t)IP_MIN_HDR_SIZE,					(size_t)udp_io_hdr->uih_ip_opt_len);				for (tmp_acc= ipopt_pack; tmp_acc->acc_next;					tmp_acc= tmp_acc->acc_next);assert (tmp_acc->acc_linkC == 1);				tmp_acc->acc_next= no_ipopt_pack->acc_next;				if (tmp_acc->acc_next)					tmp_acc->acc_next->acc_linkC++;			}			pack= ipopt_pack;		}		else			pack= no_ipopt_pack;		if (udp_fd->uf_rd_buf)		{			if ((flags & NWUO_ACC_MASK) == NWUO_SHARED)			{				share_fd= udp_fd;				continue;			}#if DEBUG { where(); printf("throwing away packet\n"); }#endif			bf_afree(udp_fd->uf_rd_buf);		}		udp_fd->uf_rd_buf= pack;		pack->acc_linkC++;		udp_fd->uf_exp_tim= exp_tim;		if ((flags & NWUO_ACC_MASK) == NWUO_SHARED ||			(flags & NWUO_ACC_MASK) ==  NWUO_EXCL)		{			if (ipopt_pack)			{				bf_afree(ipopt_pack);				ipopt_pack= 0;			}assert(no_ipopt_pack);			bf_afree(no_ipopt_pack);			no_ipopt_pack= 0;		}		if (udp_fd->uf_flags & UFF_READ_IP)		{#if DEBUG & 256 { where(); printf("%d calling packet2user\n", i); }#endif			udp_packet2user(udp_fd);		}		else		{#if DEBUG & 256 { where(); printf("%d not READ_IP\n", i); }#endif		}		if ((flags & NWUO_ACC_MASK) == NWUO_SHARED ||			(flags & NWUO_ACC_MASK) ==  NWUO_EXCL)		{			break;		}	}	if (share_fd && no_ipopt_pack)	{		bf_afree(share_fd->uf_rd_buf);		if (share_fd->uf_udpopt.nwuo_flags & NWUO_EN_IPOPT)			pack= ipopt_pack;		else			pack= no_ipopt_pack;		pack->acc_linkC++;		share_fd->uf_rd_buf= pack;		share_fd->uf_exp_tim= exp_tim;		if (ipopt_pack)		{			bf_afree(ipopt_pack);			ipopt_pack= 0;		}assert (no_ipopt_pack);		bf_afree(no_ipopt_pack);		no_ipopt_pack= 0;	}	else	{		if (ipopt_pack)			bf_afree(ipopt_pack);		if (no_ipopt_pack)			bf_afree(no_ipopt_pack);	}assert (ip_acc);	bf_afree(ip_acc);assert (udp_acc);	bf_afree(udp_acc);}PUBLIC void udp_close(fd)int fd;{	udp_fd_t *udp_fd;#if DEBUG { where(); printf("udp_close (%d)\n", fd); }#endif	udp_fd= &udp_fd_table[fd];	assert (udp_fd->uf_flags & UFF_INUSE);	udp_fd->uf_flags= UFF_EMPTY;	if (udp_fd->uf_rd_buf)	{		bf_afree(udp_fd->uf_rd_buf);		udp_fd->uf_rd_buf= 0;	}}PUBLIC int udp_write(fd, count)int fd;size_t count;{	udp_fd_t *udp_fd;	udp_port_t *udp_port;	udp_fd= &udp_fd_table[fd];	udp_port= udp_fd->uf_port;	if (!(udp_fd->uf_flags & UFF_OPTSET))	{		reply_thr_get (udp_fd, EBADMODE, FALSE);		return NW_OK;	}assert (!(udp_fd->uf_flags & UFF_WRITE_IP));	udp_fd->uf_wr_count= count;	udp_fd->uf_flags |= UFF_WRITE_IP;	restart_write_fd(udp_fd);	if (udp_fd->uf_flags & UFF_WRITE_IP)	{#if DEBUG  { where(); printf("replying NW_SUSPEND\n"); }#endif		return NW_SUSPEND;	}	else	{#if DEBUG & 256 { where(); printf("replying NW_OK\n"); }#endif		return NW_OK;	}}PRIVATE void restart_write_fd(udp_fd)udp_fd_t *udp_fd;{	udp_port_t *udp_port;	acc_t *pack, *ip_hdr_pack, *udp_hdr_pack, *ip_opt_pack, *user_data;	udp_hdr_t *udp_hdr;	udp_io_hdr_t *udp_io_hdr;	ip_hdr_t *ip_hdr;	size_t ip_opt_size, user_data_size;	unsigned long flags;	u16_t chksum;	u8_t u16[2];	int result;	udp_port= udp_fd->uf_port;	if (udp_port->up_flags & UPF_WRITE_IP)	{		udp_port->up_flags |= UPF_MORE2WRITE;#if DEBUG { where(); printf("\n"); }#endif		return;	}assert (udp_fd->uf_flags & UFF_WRITE_IP);	udp_fd->uf_flags &= ~UFF_WRITE_IP;assert (!udp_port->up_wr_pack);	pack= (*udp_fd->uf_get_userdata)(udp_fd->uf_srfd, 0,		udp_fd->uf_wr_count, FALSE);	if (!pack)	{		udp_fd->uf_flags &= ~UFF_WRITE_IP;		reply_thr_get (udp_fd, EFAULT, FALSE);#if DEBUG { where(); printf("\n"); }#endif		return;	}	flags= udp_fd->uf_udpopt.nwuo_flags;	ip_hdr_pack= bf_memreq(IP_MIN_HDR_SIZE);	ip_hdr= (ip_hdr_t *)ptr2acc_data(ip_hdr_pack);	udp_hdr_pack= bf_memreq(UDP_HDR_SIZE);	udp_hdr= (udp_hdr_t *)ptr2acc_data(udp_hdr_pack);	if (flags & NWUO_RWDATALL)	{		pack= bf_packIffLess(pack, UDP_IO_HDR_SIZE);		udp_io_hdr= (udp_io_hdr_t *)ptr2acc_data(pack);		ip_opt_size= udp_io_hdr->uih_ip_opt_len;		user_data_size= udp_io_hdr->uih_data_len;		if (UDP_IO_HDR_SIZE+ip_opt_size>udp_fd->uf_wr_count)		{			bf_afree(ip_hdr_pack);			bf_afree(udp_hdr_pack);			bf_afree(pack);			reply_thr_get (udp_fd, EINVAL, FALSE);#if DEBUG { where(); printf("\n"); }#endif			return;		}		if (ip_opt_size & 3)		{			bf_afree(ip_hdr_pack);			bf_afree(udp_hdr_pack);			bf_afree(pack);			reply_thr_get (udp_fd, EFAULT, FALSE);#if DEBUG { where(); printf("\n"); }#endif			return;		}		if (ip_opt_size)			ip_opt_pack= bf_cut(pack, UDP_IO_HDR_SIZE, ip_opt_size);		else			ip_opt_pack= 0;		user_data_size= udp_fd->uf_wr_count-UDP_IO_HDR_SIZE-			ip_opt_size;		user_data= bf_cut(pack, UDP_IO_HDR_SIZE+ip_opt_size, 			user_data_size);		bf_afree(pack);	}	else	{		udp_io_hdr= 0;		ip_opt_size= 0;		user_data_size= udp_fd->uf_wr_count;		ip_opt_pack= 0;		user_data= pack;	}	ip_hdr->ih_vers_ihl= (IP_MIN_HDR_SIZE+ip_opt_size) >> 2;	ip_hdr->ih_tos= UDP_TOS;	ip_hdr->ih_flags_fragoff= HTONS(UDP_IP_FLAGS);	ip_hdr->ih_ttl= UDP_TTL;	ip_hdr->ih_proto= IPPROTO_UDP;	if (flags & NWUO_RA_SET)	{#if DEBUG { where(); printf("NWUO_RA_SET\n"); }#endif		ip_hdr->ih_dst= udp_fd->uf_udpopt.nwuo_remaddr;	}	else	{assert (udp_io_hdr);		ip_hdr->ih_dst= udp_io_hdr->uih_dst_addr;	}#if DEBUG & 256 { where(); printf("ih_dst= "); writeIpAddr(ip_hdr->ih_dst); printf("\n"); }#endif	if ((flags & NWUO_LOCPORT_MASK) != NWUO_LP_ANY)		udp_hdr->uh_src_port= udp_fd->uf_udpopt.nwuo_locport;	else	{assert (udp_io_hdr);		udp_hdr->uh_src_port= udp_io_hdr->uih_src_port;	}	if (flags & NWUO_RP_SET)		udp_hdr->uh_dst_port= udp_fd->uf_udpopt.nwuo_remport;	else	{assert (udp_io_hdr);		udp_hdr->uh_dst_port= udp_io_hdr->uih_dst_port;	}	udp_hdr->uh_length= htons(UDP_HDR_SIZE+user_data_size);	udp_hdr->uh_chksum= 0;	udp_hdr_pack->acc_next= user_data;	chksum= pack_oneCsum(udp_hdr_pack);	chksum= oneC_sum(chksum, (u16_t *)&udp_fd->uf_port->up_ipaddr,		sizeof(ipaddr_t));	chksum= oneC_sum(chksum, (u16_t *)&ip_hdr->ih_dst, sizeof(ipaddr_t));	u16[0]= 0;	u16[1]= IPPROTO_UDP;	chksum= oneC_sum(chksum, (u16_t *)u16, sizeof(u16));	chksum= oneC_sum(chksum, (u16_t *)&udp_hdr->uh_length, sizeof(u16_t));	if (~chksum)		chksum= ~chksum;	udp_hdr->uh_chksum= chksum;		if (ip_opt_pack)	{		ip_opt_pack= bf_packIffLess(ip_opt_pack, ip_opt_size);		ip_opt_pack->acc_next= udp_hdr_pack;		udp_hdr_pack= ip_opt_pack;	}	ip_hdr_pack->acc_next= udp_hdr_pack;assert (!udp_port->up_wr_pack);assert (!(udp_port->up_flags & UPF_WRITE_IP));	udp_port->up_wr_pack= ip_hdr_pack;	udp_port->up_flags |= UPF_WRITE_IP;#if DEBUG & 256 { where(); printf("calling ip_write(%d, %d)\n", udp_port->up_ipfd,	bf_bufsize(ip_hdr_pack)); }#endif	result= ip_write(udp_port->up_ipfd, bf_bufsize(ip_hdr_pack));#if DEBUG & 256 { where(); printf("ip_write done\n"); }#endif	if (result == NW_SUSPEND)	{		udp_port->up_flags |= UPF_WRITE_SP;		udp_fd->uf_flags |= UFF_WRITE_IP;		udp_port->up_write_fd= udp_fd;	}	else if (result<0)		reply_thr_get(udp_fd, result, FALSE);	else		reply_thr_get (udp_fd, udp_fd->uf_wr_count, FALSE);#if DEBUG & 256 { where(); printf("\n"); }#endif}PRIVATE u16_t pack_oneCsum(pack)acc_t *pack;{	u16_t prev;	int odd_byte;	char *data_ptr;	int length;	char byte_buf[2];	assert (pack);	prev= 0;	odd_byte= FALSE;	for (; pack; pack= pack->acc_next)	{				data_ptr= ptr2acc_data(pack);		length= pack->acc_length;		if (!length)			continue;		if (odd_byte)		{			byte_buf[1]= *data_ptr;			prev= oneC_sum(prev, (u16_t *)byte_buf, 2);			data_ptr++;			length--;			odd_byte= FALSE;		}		if (length & 1)		{			odd_byte= TRUE;			length--;			byte_buf[0]= data_ptr[length];		}		if (!length)			continue;		prev= oneC_sum (prev, (u16_t *)data_ptr, length);	}	if (odd_byte)		prev= oneC_sum (prev, (u16_t *)byte_buf, 1);	return prev;}PRIVATE void udp_restart_write_port(udp_port )udp_port_t *udp_port;{	udp_fd_t *udp_fd;	int i;assert (!udp_port->up_wr_pack);assert (!(udp_port->up_flags & (UPF_WRITE_IP|UPF_WRITE_SP)));	while (udp_port->up_flags & UPF_MORE2WRITE)	{		udp_port->up_flags &= ~UPF_MORE2WRITE;		for (i= 0, udp_fd= udp_port->up_next_fd; i<UDP_FD_NR;			i++, udp_fd++)		{			if (udp_fd == &udp_fd_table[UDP_FD_NR])				udp_fd= udp_fd_table;			if (!(udp_fd->uf_flags & UFF_INUSE))				continue;			if (!(udp_fd->uf_flags & UFF_WRITE_IP))				continue;			if (udp_fd->uf_port != udp_port)				continue;			restart_write_fd(udp_fd);			if (udp_port->up_flags & UPF_WRITE_IP)			{				udp_port->up_next_fd= udp_fd+1;				udp_port->up_flags |= UPF_MORE2WRITE;				return;			}		}	}}PUBLIC int udp_cancel(fd, which_operation)int fd;int which_operation;{	udp_fd_t *udp_fd;#if DEBUG { where(); printf("udp_cancel(%d, %d)\n", fd, which_operation); }#endif	udp_fd= &udp_fd_table[fd];	switch (which_operation)	{	case SR_CANCEL_READ:assert (udp_fd->uf_flags & UFF_READ_IP);		udp_fd->uf_flags &= ~UFF_READ_IP;		reply_thr_put(udp_fd, EINTR, FALSE);		break;	case SR_CANCEL_WRITE:assert (udp_fd->uf_flags & UFF_WRITE_IP);		udp_fd->uf_flags &= ~UFF_WRITE_IP;		if (udp_fd->uf_port->up_write_fd == udp_fd)			udp_fd->uf_port->up_write_fd= NULL;		reply_thr_get(udp_fd, EINTR, FALSE);		break;	case SR_CANCEL_IOCTL:assert (udp_fd->uf_flags & UFF_IOCTL_IP);		udp_fd->uf_flags &= ~UFF_IOCTL_IP;		reply_thr_get(udp_fd, EINTR, TRUE);		break;	default:		ip_panic(( "got unknown cancel request" ));	}	return NW_OK;}PRIVATE void udp_buffree (priority, reqsize)int priority;size_t reqsize;{	int i;	time_t curr_tim;	if (priority <UDP_PRI_EXP_FDBUFS)		return;	curr_tim= get_time();	for (i=0; i<UDP_FD_NR; i++)	{		if (!(udp_fd_table[i].uf_flags & UFF_INUSE) )			continue;		if (udp_fd_table[i].uf_rd_buf &&			udp_fd_table[i].uf_exp_tim < curr_tim)		{			bf_afree(udp_fd_table[i].uf_rd_buf);			udp_fd_table[i].uf_rd_buf= 0;			if (bf_free_buffsize >= reqsize)				return;		}	}	if (priority <UDP_PRI_FDBUFS)		return;	for (i=0; i<UDP_FD_NR; i++)	{		if (!(udp_fd_table[i].uf_flags & UFF_INUSE))			continue;		if (udp_fd_table[i].uf_rd_buf)		{			bf_afree(udp_fd_table[i].uf_rd_buf);			udp_fd_table[i].uf_rd_buf= 0;			if (bf_free_buffsize >= reqsize)				return;		}	}}

⌨️ 快捷键说明

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