天天看點

核心中的UDP socket流程(3)——sock_create

核心中的UDP socket流程(3)——sock_create作者:[email protected]

由于種種原因,工作的,私人的,學習停了幾天。周末的時候,一天生病,還把《讓子彈飛》和《非常勿擾2》看了。這兩個片子還真火,幾乎滿座啊。非2遠沒有子彈好看,甚至還不如虎頭蛇尾的《趙氏孤兒》呢。

好了,閑話少說。上次看到了sys_socket調用sock_create的地方了。下面開始研究sock_create了。

sys_socket将自己的參數family, type, protocol傳給sock_create,而sock為sock_create的輸出值。

retval = sock_create(family, type, protocol, &sock);

下面看sock_create的代碼

int sock_create(int family, int type, int protocol, struct socket **res)

{

    return __sock_create(current->nsproxy->net_ns, family, type, protocol, res, 0);

}

sock_create不過是一個包裝函數,它通過__sock_create真正的去建立socket。其中,current是目前task的指針——實際上current是一個宏,這個宏在linux核心中已經存在很久了。task的類型為struct task_struct。nsproxy是它的一個成員變量,是task的命名空間指針,下面是它的定義:

struct nsproxy {

    atomic_t count;

    struct uts_namespace *uts_ns;

    struct ipc_namespace *ipc_ns;

    struct mnt_namespace *mnt_ns;

    struct pid_namespace *pid_ns;

    struct net      *net_ns;

};

ipc_ns:儲存所有與程序通信(IPC)有關的資訊

mnt_ns:儲存已mount的檔案系統資訊;

pid_ns:有關程序ID的資訊;

net_ns:這是與咱們有關的,包含所有網絡相關的命名空間。

這是第一個參數。

最後一個參數,則表明這個建立的socket是否為kernel層建立的。對于我們來說,這個socket是為應用層建立的,所有最後一個參數是0.

下面開始分析__sock_create

static int __sock_create(struct net *net, int family, int type, int protocol,

             struct socket **res, int kern)

    int err;

    struct socket *sock;

    const struct net_proto_family *pf;

    /*

     * Check protocol is in range

     */

    if (family 0 || family >= NPROTO)

        return -EAFNOSUPPORT;

    if (type 0 || type >= SOCK_MAX)

        return -EINVAL;

     /*

     * Skip some codes

首先這個函數,先對family和type進行檢查,檢視是否超出正常範圍。

唉,又12點了,明天再見了!

繼續閱讀