INET LAYER--UDP socket

struct udp_sock

struct udp_sock 代表一个UDP socket,其结构如下:

struct udp_sock 
{
	struct inet_sock inet
	{
		struct sock sk;
		… …
		INET specified
		… …
	}
	… …
	UDP specified
	… …
}

UDP socket创建

当通过系统调用创建一个UDP socket时,内核中的处理流程如下:

socket(AF_INET,SOCK_DGRAM, 0)
	__sys_socket(AF_INET,SOCK_DGRAM, 0)
		sock_create(AF_INET,SOCK_DGRAM, 0, &sock)
			__sock_create(current->nsproxy->net_ns, AF_INET, SOCK_DGRAM, 0, &sock, 0)
				1.分配struct socket结构
					struct socket *sock;
					sock = sock_alloc();
					sock->type = SOCK_DGRAM;
					
				2.调用AF_INET层处理函数
					net_families[AF_INET]->create(net, sock, 0, 0)
					
	sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK))

在inet_init中,调用sock_register(&inet_family_ops)将inet_family_ops结构体加入net_families数组,所以net_families[AF_INET]->create就是inet_create:

static const struct net_proto_family inet_family_ops = {
	.family = PF_INET,
	.create = inet_create,
	.owner	= THIS_MODULE,
};

inet_create 处理流程如下:

inet_create((struct net *)net, (struct socket *)sock, 0 ,0)
	1.根椐SOCK TYPE 查找创建UDP socket 所需的struct inet_protosw结构体:
		struct inet_protosw
		{
		.type =       SOCK_DGRAM,
		.protocol =   IPPROTO_UDP,
		.prot =       &udp_prot,
		.ops =        &inet_dgram_ops,
		.flags =      INET_PROTOSW_PERMANENT,
       },
    
    2.分配struct sock结构,实际分配了struct udp_sock类型的结构体。
		sk = sk_alloc(net, PF_INET, GFP_KERNEL, &udp_prot, 0)

   	3.初始化结构体成员。
   		struct socket *sock
   		//struct socket
   		sock->state = SS_UNCONNECTED
   		sock->type = SOCK_DGRAM
   		sock->ops = &inet_dgram_ops
		
		//struct sock
		sk = sock->sk
   		sk->sk_family = PF_INET
   		sk->sk_prot_creator = &udp_prot
   		sk->sk_kern_sock = 0
   		sk->sk_reuse = 0
   		sk->sk_tx_queue_mapping = NO_QUEUE_MAPPING
   		sk->sk_send_head	=	NULL
   		sk->sk_allocation	=	GFP_KERNEL;
		sk->sk_rcvbuf		=	sysctl_rmem_default;
		sk->sk_sndbuf		=	sysctl_wmem_default;
		sk->sk_socket = sock
		sk->sk_type = SOCK_DGRAM
		sk->sk_rcvtimeo		=	MAX_SCHEDULE_TIMEOUT;
		sk->sk_sndtimeo		=	MAX_SCHEDULE_TIMEOUT;		
		sk->sk_state_change	=	sock_def_wakeup;
		sk->sk_data_ready	=	sock_def_readable;
		sk->sk_write_space	=	sock_def_write_space;
		sk->sk_error_report	=	sock_def_error_report;
		sk->sk_write_pending	=	0;
		sk->sk_rcvlowat		=	1;
		sk->sk_destruct	   = inet_sock_destruct;
		sk->sk_protocol	   = protocol;
		sk->sk_backlog_rcv = &udp_prot->backlog_rcv;
		sk->sk_destruct = udp_destruct_sock
		
		//struct inet_sock
		inet = inet_sk(sk)
		inet->is_icsk = 0
		inet->nodefrag = 0
		inet->uc_ttl	= -1;
		inet->mc_loop	= 1;
		inet->mc_ttl	= 1;
		inet->mc_all	= 1;
		inet->mc_index	= 0;
		inet->mc_list	= NULL;
		inet->rcv_tos	= 0;	
			
		//struct sock_common
		sock->sk->__sk_common.skc_prot = &udp_prot
		sock->sk->__sk_common.skc_net_refcnt = 0
		__sk_common.skc_net = net
		

上一篇:socket函数


下一篇:Linux网络编程之UDP Socket(二)