核心:2.6.34
TCP是應用最廣泛的傳輸層協議,其提供了連線導向的、可靠的位元組流服務,但 也正是因為這些特性,使得TCP較之UDP異常複雜,還是分兩部分[建立與使用]來進行分析。這篇主要包括TCP的建立及三向交握 的過程。
編程時一般用如下語句建立TCP Socket:
socket(AF_INET, SOCK_DGRAM, IPPROTO_TCP)
由此開始分析,調用介面[net/socket.c]: SYSCALL_DEFINE3(socket)
其中執行兩步關鍵操作:sock_create()與sock_map_fd()
retval = sock_create(family, type, protocol, &sock); if (retval < 0) goto out;retval = sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK));if (retval < 0) goto out_release;
sock_create()用於建立socket,sock_map_fd()將之映射到檔案描述符,使socket能通過 fd進行訪問,著重分析sock_create()的建立過程。
sock_create() -> __sock_create()
從__sock_create()代碼看到建立包含兩步:sock_alloc()和pf->create()。sock_alloc()分配了 sock記憶體空間並初始化inode;pf->create()初始化了sk。
sock = sock_alloc();sock->type = type;……pf = rcu_dereference(net_families[family]);……pf->create(net, sock, protocol, kern);
sock_alloc()
分配空間,通過 new_inode()分配了節點(包括socket),然後通過SOCKET_I宏獲得sock,實際上inode和sock是在new_inode()中一起分配的,結 構體叫作sock_alloc。
inode = new_inode(sock_mnt->mnt_sb); sock = SOCKET_I(inode);
設定inode的參數,並返回sock。
inode->i_mode = S_IFSOCK | S_IRWXUGO; inode->i_uid = current_fsuid(); inode->i_gid = current_fsgid(); return sock;
繼續往下看具體的建立過程:new_inode(),在分配後,會設定i_ino和i_state的值。
struct inode *new_inode(struct super_block *sb) { …… inode = alloc_inode(sb); if (inode) { spin_lock(&inode_lock); __inode_add_to_lists(sb, NULL, inode); inode->i_ino = ++last_ino; inode->i_state = 0; spin_unlock(&inode_lock); } return inode; }
其中的alloc_inode() -> sb->s_op->alloc_inode(),sb是sock_mnt->mnt_sb,所以alloc_inode()指 向的是sockfs的操作函數sock_alloc_inode。
static const struct super_operations sockfs_ops = { .alloc_inode = sock_alloc_inode, .destroy_inode =sock_destroy_inode, .statfs = simple_statfs, };