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