struct socket構造の詳細
8997 ワード
ユーザがsocketシステムを使用してアプリケーションの作成を呼び出すと、ソケット記述子と呼ばれるすべての操作が1つの数字で表されます.システム呼び出しの実装関数では、この数字はsocketを表す構造体にマッピングされ、この構造体はsocketのすべての属性とデータを保存します.カーネルのプロトコル実装では,socketを表す構造体について,比較的複雑なものであり,以下で紹介する.
struct socket.
これは基本的なBSD socketであり、socketシステム呼び出しによって作成された様々な異なるタイプのsocketを呼び出し、作成を開始したのはすべてそれであり、その後、様々な異なるタイプのsocketがそれに基づいて様々な拡張を行う.struct socketは仮想ファイルシステム上で作成され、ファイルと見なすことができ、安全に拡張することができます.以下に完全な定義を示します.
stateはsocketが置かれている状態を表すために使用され、列挙変数であり、そのタイプは以下のように定義されています.
このメンバーは、tcpのみが接続向けプロトコルであるため、udpとrawはsocket状態を維持する必要がないため、TCP socketにのみ有用である.
flagsはフラグビットのセットであり、カーネルでは使用されていない.
opsはプロトコルに関連する一連の操作セットであり、構造体struct proto_opsの定義は以下の通りです.
typeはsocketのタイプで、対応する値は以下の通りです.
skはネットワーク層のsocketの表現であり、構造体struct sockは比較的膨大であり、ここでは詳細にはリストされず、重要なメンバーだけを紹介している.
sk_protとsk_prot_creator、この2つのメンバーは特定のプロトコル処理関数セットを指し、そのタイプは構造体struct protoであり、この構造体もstruct proto_と同じである.opsに似たプロトコル操作関数セットのセット.この2つの概念は少し混同されているようですが、struct proto_opsのメンバーはstruct socket階層上のデータを操作し、処理が完了し、メンバーsk->skを呼び出すprotの関数はstruct sock階層上のデータを操作します.つまり、それらの間には階層的な違いがあります.struct protoタイプの変数はプロトコルスタックに全部で3つあり、それぞれmytcp_である.prot,myudp_prot,myraw_Protは、TCP、UDP、RAWプロトコルに対応します.
sk_stateはsocketの現在の接続状態を表し、struct socketのstateよりも細かい状態であり、その可能な値は以下の通りである.
これらの値は名前から見るとTCPプロトコルのみで使用されているようですが、実際にはUDPとRAWもいくつかの値を借りており、1つのsocketが作成された当初はTCP_CLOSE、UDPソケット接続が完了したら、この値をTCP_に変更します.ESTABLISHED、最後に、socktを閉じてTCPに戻るCLOSE、RAWも同じです.
sk_rcvbufとsk_sndbufは、受信バッファと送信バッファのサイズをそれぞれ表す.sk_receive_queueとsk_write_Queueはそれぞれ受信バッファキューと送信バッファキューであり、キューにはソケットバッファstruct sk_が並んでいるbuff,キュー内のstruct sk_buffのバイト数の合計はバッファサイズの設定を超えてはいけません.
続いて前編ではstruct sockについて引き続きご紹介します.
sk_rmem_alloc, sk_wmem_allocとsk_omem_allocは、バッファの使用状況を追跡するために、受信バッファキュー、送信バッファキュー、および他のバッファキューに割り当てられたバイト数をそれぞれ表す.
struct sockにはstruct sockがありますcommonメンバー、struct inet_timewait_sockも使用するので、構造体に単独で分類します.定義は次のとおりです.
struct inet_sock.
これはINETドメイン専用のsocket表現で、struct sockに基づいて拡張され、基本的なsocketの属性がすでに備えられている上で、struct inet_sockは、TTL、マルチキャストリスト、IPアドレス、ポートなど、INETドメイン固有のいくつかの属性を提供しています.以下は、その完全な定義です.
struct raw_sock
これはRAWプロトコル専用のsocketの表現で、struct inet_RAWプロトコルはICMPプロトコルのフィルタ設定を処理するため、以下のように定義されている.
struct udp_sock
これはUDPプロトコル専用のsocket表現で、struct inet_sockベースの拡張は、以下のように定義されています.
struct inet_connection_sock
上の2つを見て、3つ目はstruct tcpだと思います.だが実際はstruct tcpsockはstruct inetから直接sock上で拡張するのではなくstruct inet_からconnection_sockベースで拡張、struct inet_connection_sockは接続向けのすべてのsocketの表現であり,このsocket,および以下のすべてのtcpに関連するsocketについて,tcp実装を解析する際に詳細に説明するが,ここではそれらの関係のみをリストする.
strcut tcp_sock
これはTCPプロトコル専用のsocket表現でありstruct inet_connection_sockベースは拡張され,主にスライドウィンドウプロトコルを追加し,混雑アルゴリズムなどのTCP固有属性を回避した.
struct inet_timewait_sock
struct tcp_timewait_sock
struct inet_timewait_sockに基づいて拡張します.
struct inet_request_sock
struct tcp_request_sock
struct inet_request_sockに基づいて拡張します.
struct socket.
これは基本的なBSD socketであり、socketシステム呼び出しによって作成された様々な異なるタイプのsocketを呼び出し、作成を開始したのはすべてそれであり、その後、様々な異なるタイプのsocketがそれに基づいて様々な拡張を行う.struct socketは仮想ファイルシステム上で作成され、ファイルと見なすことができ、安全に拡張することができます.以下に完全な定義を示します.
struct socket {
socket_state state;
unsigned long flags;
const struct proto_ops *ops;
struct fasync_struct *fasync_list;
struct file *file;
struct sock *sk;
wait_queue_head_t wait;
short type;
};
stateはsocketが置かれている状態を表すために使用され、列挙変数であり、そのタイプは以下のように定義されています.
typedef enum {
SS_FREE = 0, // socket
SS_UNCONNECTED, // socket
SS_CONNECTING, //
SS_CONNECTED, // socket
SS_DISCONNECTING //
}socket_state;
このメンバーは、tcpのみが接続向けプロトコルであるため、udpとrawはsocket状態を維持する必要がないため、TCP socketにのみ有用である.
flagsはフラグビットのセットであり、カーネルでは使用されていない.
opsはプロトコルに関連する一連の操作セットであり、構造体struct proto_opsの定義は以下の通りです.
struct proto_ops {
int family;
struct module *owner;
int (*release)(struct socket *sock);
int (*bind)(struct socket *sock, struct sockaddr *myaddr, int sockaddr_len);
int (*connect)(struct socket *sock, struct sockaddr *vaddr, int sockaddr_len, int flags);
int (*socketpair)(struct socket *sock1, struct socket *sock2);
int (*accept)(struct socket *sock,struct socket *newsock, int flags);
int (*getname)(struct socket *sock, struct sockaddr *addr,int *sockaddr_len, int peer);
unsigned int (*poll)(struct file *file, struct socket *sock,
struct poll_table_struct *wait);
int (*ioctl)(struct socket *sock, unsigned int cmd, unsigned long arg);
int (*listen)(struct socket *sock, int len);
int (*shutdown)(struct socket *sock, int flags);
int (*setsockopt)(struct socket *sock, int level,
int optname, char __user *optval, int optlen);
int (*getsockopt)(struct socket *sock, int level,
int optname, char __user *optval, int __user *optlen);
int (*sendmsg)(struct kiocb *iocb, struct socket *sock,
struct msghdr *m, size_t total_len);
int (*recvmsg)(struct kiocb *iocb, struct socket *sock,
struct msghdr *m, size_t total_len, int flags);
int (*mmap)(struct file *file, struct socket *sock,struct vm_area_struct * vma);
ssize_t (*sendpage)(struct socket *sock, struct page *page,
int offset, size_t size, int flags);
};
プロトコルスタックには、合計3つのstrcut proto_が定義されています.opsタイプの変数、それぞれmyinet_stream_ops, myinet_dgram_ops, myinet_sockraw_ops,ストリームプロトコル,データレポート,および元のインタフェースプロトコルに対する操作関数セット.typeはsocketのタイプで、対応する値は以下の通りです.
enum sock_type {
SOCK_DGRAM = 1,
SOCK_STREAM = 2,
SOCK_RAW = 3,
SOCK_RDM = 4,
SOCK_SEQPACKET = 5,
SOCK_DCCP = 6,
SOCK_PACKET = 10,
};
skはネットワーク層のsocketの表現であり、構造体struct sockは比較的膨大であり、ここでは詳細にはリストされず、重要なメンバーだけを紹介している.
sk_protとsk_prot_creator、この2つのメンバーは特定のプロトコル処理関数セットを指し、そのタイプは構造体struct protoであり、この構造体もstruct proto_と同じである.opsに似たプロトコル操作関数セットのセット.この2つの概念は少し混同されているようですが、struct proto_opsのメンバーはstruct socket階層上のデータを操作し、処理が完了し、メンバーsk->skを呼び出すprotの関数はstruct sock階層上のデータを操作します.つまり、それらの間には階層的な違いがあります.struct protoタイプの変数はプロトコルスタックに全部で3つあり、それぞれmytcp_である.prot,myudp_prot,myraw_Protは、TCP、UDP、RAWプロトコルに対応します.
sk_stateはsocketの現在の接続状態を表し、struct socketのstateよりも細かい状態であり、その可能な値は以下の通りである.
enum {
TCP_ESTABLISHED = 1,
TCP_SYN_SENT,
TCP_SYN_RECV,
TCP_FIN_WAIT1,
TCP_FIN_WAIT2,
TCP_TIME_WAIT,
TCP_CLOSE,
TCP_CLOSE_WAIT,
TCP_LAST_ACK,
TCP_LISTEN,
TCP_CLOSING,
TCP_MAX_STATES
};
これらの値は名前から見るとTCPプロトコルのみで使用されているようですが、実際にはUDPとRAWもいくつかの値を借りており、1つのsocketが作成された当初はTCP_CLOSE、UDPソケット接続が完了したら、この値をTCP_に変更します.ESTABLISHED、最後に、socktを閉じてTCPに戻るCLOSE、RAWも同じです.
sk_rcvbufとsk_sndbufは、受信バッファと送信バッファのサイズをそれぞれ表す.sk_receive_queueとsk_write_Queueはそれぞれ受信バッファキューと送信バッファキューであり、キューにはソケットバッファstruct sk_が並んでいるbuff,キュー内のstruct sk_buffのバイト数の合計はバッファサイズの設定を超えてはいけません.
続いて前編ではstruct sockについて引き続きご紹介します.
sk_rmem_alloc, sk_wmem_allocとsk_omem_allocは、バッファの使用状況を追跡するために、受信バッファキュー、送信バッファキュー、および他のバッファキューに割り当てられたバイト数をそれぞれ表す.
struct sockにはstruct sockがありますcommonメンバー、struct inet_timewait_sockも使用するので、構造体に単独で分類します.定義は次のとおりです.
struct sock_common {
unsigned short skc_family;
volatile unsigned char skc_state;
unsigned char skc_reuse;
int skc_bound_dev_if;
struct hlist_node skc_node;
struct hlist_node skc_bind_node;
atomic_t skc_refcnt;
unsigned int skc_hash;
struct proto *skc_prot;
};
struct inet_sock.
これはINETドメイン専用のsocket表現で、struct sockに基づいて拡張され、基本的なsocketの属性がすでに備えられている上で、struct inet_sockは、TTL、マルチキャストリスト、IPアドレス、ポートなど、INETドメイン固有のいくつかの属性を提供しています.以下は、その完全な定義です.
struct inet_sock {
struct sock sk;
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
struct ipv6_pinfo *pinet6;
#endif
__u32 daddr; //IPv4 。
__u32 rcv_saddr; //IPv4 。
__u16 dport; // 。
__u16 num; // ( )。
__u32 saddr; // 。
__s16 uc_ttl; // ttl。
__u16 cmsg_flags;
struct ip_options *opt;
__u16 sport; // 。
__u16 id; // , iphdr id 。
__u8 tos; // 。
__u8 mc_ttl; // ttl
__u8 pmtudisc;
__u8 recverr:1,
is_icsk:1,
freebind:1,
hdrincl:1, // ip ( raw )
mc_loop:1; // 。
int mc_index; // 。
__u32 mc_addr; // 。
struct ip_mc_socklist *mc_list; // 。
struct {
unsigned int flags;
unsigned int fragsize;
struct ip_options *opt;
struct rtable *rt;
int length;
u32 addr;
struct flowi fl;
} cork;
};
struct raw_sock
これはRAWプロトコル専用のsocketの表現で、struct inet_RAWプロトコルはICMPプロトコルのフィルタ設定を処理するため、以下のように定義されている.
struct raw_sock {
struct inet_sock inet;
struct icmp_filter filter;
};
struct udp_sock
これはUDPプロトコル専用のsocket表現で、struct inet_sockベースの拡張は、以下のように定義されています.
struct udp_sock {
struct inet_sock inet;
int pending;
unsigned int corkflag;
__u16 encap_type;
__u16 len;
};
struct inet_connection_sock
上の2つを見て、3つ目はstruct tcpだと思います.だが実際はstruct tcpsockはstruct inetから直接sock上で拡張するのではなくstruct inet_からconnection_sockベースで拡張、struct inet_connection_sockは接続向けのすべてのsocketの表現であり,このsocket,および以下のすべてのtcpに関連するsocketについて,tcp実装を解析する際に詳細に説明するが,ここではそれらの関係のみをリストする.
strcut tcp_sock
これはTCPプロトコル専用のsocket表現でありstruct inet_connection_sockベースは拡張され,主にスライドウィンドウプロトコルを追加し,混雑アルゴリズムなどのTCP固有属性を回避した.
struct inet_timewait_sock
struct tcp_timewait_sock
struct inet_timewait_sockに基づいて拡張します.
struct inet_request_sock
struct tcp_request_sock
struct inet_request_sockに基づいて拡張します.