1. <var id="fe6gj"></var>

    <rp id="fe6gj"><nav id="fe6gj"></nav></rp>

    <noframes id="fe6gj"><cite id="fe6gj"></cite>

    <ins id="fe6gj"><button id="fe6gj"><p id="fe6gj"></p></button></ins>
    1. <tt id="fe6gj"><i id="fe6gj"><sub id="fe6gj"></sub></i></tt>
        始創于2000年 股票代碼:831685
        咨詢熱線:0371-60135900 注冊有禮 登錄
        • 掛牌上市企業
        • 60秒人工響應
        • 99.99%連通率
        • 7*24h人工
        • 故障100倍補償
        您的位置: 網站首頁 > 幫助中心>文章內容

        Linux內核--網絡協議棧深入分析(三)--INET協議族socket和傳輸層sock

        發布時間:  2012/9/15 20:35:36

        本文分析基于Linux Kernel 3.2.1

        原創作品,轉載請標明http://blog.csdn.net/yming0221/article/details/7979838

        更多請查看專欄http://blog.csdn.net/column/details/linux-kernel-net.html


        Linux內核中協議族有INET協議族,UNIX協議族等,我們還是以INET協議族為例。

        下面是內核中的協議族聲明:

         

        1. /* Supported address families. */  
        2. #define AF_UNSPEC   0   
        3. #define AF_UNIX     1   /* Unix domain sockets      */   
        4. #define AF_LOCAL    1   /* POSIX name for AF_UNIX   */   
        5. #define AF_INET     2   /* Internet IP Protocol     */   
        6. #define AF_AX25     3   /* Amateur Radio AX.25      */   
        7. #define AF_IPX      4   /* Novell IPX           */   
        8. #define AF_APPLETALK    5   /* AppleTalk DDP        */   
        9. #define AF_NETROM   6   /* Amateur Radio NET/ROM    */   
        10. #define AF_BRIDGE   7   /* Multiprotocol bridge     */   
        11. #define AF_ATMPVC   8   /* ATM PVCs         */   
        12. #define AF_X25      9   /* Reserved for X.25 project    */   
        13. #define AF_INET6    10  /* IP version 6         */   
        14. #define AF_ROSE     11  /* Amateur Radio X.25 PLP   */   
        15. #define AF_DECnet   12  /* Reserved for DECnet project  */   
        16. #define AF_NETBEUI  13  /* Reserved for 802.2LLC project*/   
        17. #define AF_SECURITY 14  /* Security callback pseudo AF */   
        18. #define AF_KEY      15      /* PF_KEY key management API */   
        19. #define AF_NETLINK  16   
        20. #define AF_ROUTE    AF_NETLINK /* Alias to emulate 4.4BSD */   
        21. #define AF_PACKET   17  /* Packet family        */   
        22. #define AF_ASH      18  /* Ash              */   
        23. #define AF_ECONET   19  /* Acorn Econet         */   
        24. #define AF_ATMSVC   20  /* ATM SVCs         */   
        25. #define AF_RDS      21  /* RDS sockets          */   
        26. #define AF_SNA      22  /* Linux SNA Project (nutters!) */   
        27. #define AF_IRDA     23  /* IRDA sockets         */   
        28. #define AF_PPPOX    24  /* PPPoX sockets        */   
        29. #define AF_WANPIPE  25  /* Wanpipe API Sockets */   
        30. #define AF_LLC      26  /* Linux LLC            */   
        31. #define AF_CAN      29  /* Controller Area Network      */   
        32. #define AF_TIPC     30  /* TIPC sockets         */   
        33. #define AF_BLUETOOTH    31  /* Bluetooth sockets        */   
        34. #define AF_IUCV     32  /* IUCV sockets         */   
        35. #define AF_RXRPC    33  /* RxRPC sockets        */   
        36. #define AF_ISDN     34  /* mISDN sockets        */   
        37. #define AF_PHONET   35  /* Phonet sockets       */   
        38. #define AF_IEEE802154   36  /* IEEE802154 sockets       */   
        39. #define AF_CAIF     37  /* CAIF sockets         */   
        40. #define AF_ALG      38  /* Algorithm sockets        */   
        41. #define AF_NFC      39  /* NFC sockets          */   
        42. #define AF_MAX      40  /* For now.. */  

        內核中的PF_***和AF_***其實可以混用,它的宏定義如下:

         

         

        1. /* Protocol families, same as address families. */  
        2. #define PF_UNSPEC   AF_UNSPEC   
        3. #define PF_UNIX     AF_UNIX   
        4. #define PF_LOCAL    AF_LOCAL   
        5. #define PF_INET     AF_INET   
        6. #define PF_AX25     AF_AX25   
        7. #define PF_IPX      AF_IPX   
        8. #define PF_APPLETALK    AF_APPLETALK   
        9. #define PF_NETROM   AF_NETROM   
        10. #define PF_BRIDGE   AF_BRIDGE   
        11. #define PF_ATMPVC   AF_ATMPVC   
        12. #define PF_X25      AF_X25   
        13. #define PF_INET6    AF_INET6   
        14. #define PF_ROSE     AF_ROSE   
        15. #define PF_DECnet   AF_DECnet   
        16. #define PF_NETBEUI  AF_NETBEUI   
        17. #define PF_SECURITY AF_SECURITY   
        18. #define PF_KEY      AF_KEY   
        19. #define PF_NETLINK  AF_NETLINK   
        20. #define PF_ROUTE    AF_ROUTE   
        21. #define PF_PACKET   AF_PACKET   
        22. #define PF_ASH      AF_ASH   
        23. #define PF_ECONET   AF_ECONET   
        24. #define PF_ATMSVC   AF_ATMSVC   
        25. #define PF_RDS      AF_RDS   
        26. #define PF_SNA      AF_SNA   
        27. #define PF_IRDA     AF_IRDA   
        28. #define PF_PPPOX    AF_PPPOX   
        29. #define PF_WANPIPE  AF_WANPIPE   
        30. #define PF_LLC      AF_LLC   
        31. #define PF_CAN      AF_CAN   
        32. #define PF_TIPC     AF_TIPC   
        33. #define PF_BLUETOOTH    AF_BLUETOOTH   
        34. #define PF_IUCV     AF_IUCV   
        35. #define PF_RXRPC    AF_RXRPC   
        36. #define PF_ISDN     AF_ISDN   
        37. #define PF_PHONET   AF_PHONET   
        38. #define PF_IEEE802154   AF_IEEE802154   
        39. #define PF_CAIF     AF_CAIF   
        40. #define PF_ALG      AF_ALG   
        41. #define PF_NFC      AF_NFC   
        42. #define PF_MAX      AF_MAX  

        以后的分析就是以INET協議族為例來分析的。

         

        下面的結構體就是在系統初始化時用來管理協議族初始化的結構體:

         

        1. struct net_proto_family {  
        2.     int     family;  
        3.     int     (*create)(struct net *net, struct socket *sock,  
        4.                   int protocol, int kern);  
        5.     struct module   *owner;  
        6. };  
        第一個屬性就是協議族的宏定義,如PF_INET;

         

        第二個屬性就是協議族對應的初始化函數指針;

        INET協議族對應該結構的定義如下:

         

        1. static const struct net_proto_family inet_family_ops = {  
        2.     .family = PF_INET,  
        3.     .create = inet_create,  
        4.     .owner  = THIS_MODULE,  
        5. };  

        下面結構體是協議族操作集結構體定義:

         

         

        1. struct proto_ops {  
        2.     int     family;  
        3.     struct module   *owner;  
        4.     int     (*release)   (struct socket *sock);  
        5.     int     (*bind)      (struct socket *sock,  
        6.                       struct sockaddr *myaddr,  
        7.                       int sockaddr_len);  
        8.     int     (*connect)   (struct socket *sock,  
        9.                       struct sockaddr *vaddr,  
        10.                       int sockaddr_len, int flags);  
        11.     int     (*socketpair)(struct socket *sock1,  
        12.                       struct socket *sock2);  
        13.     int     (*accept)    (struct socket *sock,  
        14.                       struct socket *newsock, int flags);  
        15.     int     (*getname)   (struct socket *sock,  
        16.                       struct sockaddr *addr,  
        17.                       int *sockaddr_len, int peer);  
        18.     unsigned int    (*poll)      (struct file *file, struct socket *sock,  
        19.                       struct poll_table_struct *wait);  
        20.     int     (*ioctl)     (struct socket *sock, unsigned int cmd,  
        21.                       unsigned long arg);  
        22. #ifdef CONFIG_COMPAT   
        23.     int     (*compat_ioctl) (struct socket *sock, unsigned int cmd,  
        24.                       unsigned long arg);  
        25. #endif   
        26.     int     (*listen)    (struct socket *sock, int len);  
        27.     int     (*shutdown)  (struct socket *sock, int flags);  
        28.     int     (*setsockopt)(struct socket *sock, int level,  
        29.                       int optname, char __user *optval, unsigned int optlen);  
        30.     int     (*getsockopt)(struct socket *sock, int level,  
        31.                       int optname, char __user *optval, int __user *optlen);  
        32. #ifdef CONFIG_COMPAT   
        33.     int     (*compat_setsockopt)(struct socket *sock, int level,  
        34.                       int optname, char __user *optval, unsigned int optlen);  
        35.     int     (*compat_getsockopt)(struct socket *sock, int level,  
        36.                       int optname, char __user *optval, int __user *optlen);  
        37. #endif   
        38.     int     (*sendmsg)   (struct kiocb *iocb, struct socket *sock,  
        39.                       struct msghdr *m, size_t total_len);  
        40.     int     (*recvmsg)   (struct kiocb *iocb, struct socket *sock,  
        41.                       struct msghdr *m, size_t total_len,  
        42.                       int flags);  
        43.     int     (*mmap)      (struct file *file, struct socket *sock,  
        44.                       struct vm_area_struct * vma);  
        45.     ssize_t     (*sendpage)  (struct socket *sock, struct page *page,  
        46.                       int offset, size_t size, int flags);  
        47.     ssize_t     (*splice_read)(struct socket *sock,  loff_t *ppos,  
        48.                        struct pipe_inode_info *pipe, size_t len, unsigned int flags);  
        49. };  

        INET協議族中TCP和UDP協議對應的上述操作集的定義不同:

         

        TCP協議z在INET層操作集inet_stream_ops

         

        1. const struct proto_ops inet_stream_ops = {  
        2.     .family        = PF_INET,  
        3.     .owner         = THIS_MODULE,  
        4.     .release       = inet_release,  
        5.     .bind          = inet_bind,  
        6.     .connect       = inet_stream_connect,  
        7.     .socketpair    = sock_no_socketpair,  
        8.     .accept        = inet_accept,  
        9.     .getname       = inet_getname,  
        10.     .poll          = tcp_poll,  
        11.     .ioctl         = inet_ioctl,  
        12.     .listen        = inet_listen,  
        13.     .shutdown      = inet_shutdown,  
        14.     .setsockopt    = sock_common_setsockopt,  
        15.     .getsockopt    = sock_common_getsockopt,  
        16.     .sendmsg       = inet_sendmsg,  
        17.     .recvmsg       = inet_recvmsg,  
        18.     .mmap          = sock_no_mmap,  
        19.     .sendpage      = inet_sendpage,  
        20.     .splice_read       = tcp_splice_read,  
        21. #ifdef CONFIG_COMPAT   
        22.     .compat_setsockopt = compat_sock_common_setsockopt,  
        23.     .compat_getsockopt = compat_sock_common_getsockopt,  
        24.     .compat_ioctl      = inet_compat_ioctl,  
        25. #endif   
        26. };  
        UDP協議在INET層操作集inet_dgram_ops
        1. const struct proto_ops inet_dgram_ops = {  
        2.     .family        = PF_INET,  
        3.     .owner         = THIS_MODULE,  
        4.     .release       = inet_release,  
        5.     .bind          = inet_bind,  
        6.     .connect       = inet_dgram_connect,  
        7.     .socketpair    = sock_no_socketpair,  
        8.     .accept        = sock_no_accept,  
        9.     .getname       = inet_getname,  
        10.     .poll          = udp_poll,  
        11.     .ioctl         = inet_ioctl,  
        12.     .listen        = sock_no_listen,  
        13.     .shutdown      = inet_shutdown,  
        14.     .setsockopt    = sock_common_setsockopt,  
        15.     .getsockopt    = sock_common_getsockopt,  
        16.     .sendmsg       = inet_sendmsg,  
        17.     .recvmsg       = inet_recvmsg,  
        18.     .mmap          = sock_no_mmap,  
        19.     .sendpage      = inet_sendpage,  
        20. #ifdef CONFIG_COMPAT   
        21.     .compat_setsockopt = compat_sock_common_setsockopt,  
        22.     .compat_getsockopt = compat_sock_common_getsockopt,  
        23.     .compat_ioctl      = inet_compat_ioctl,  
        24. #endif   
        25. };  

        上面兩個操作集是屬于INET協議族層次,可以由協議族層套接字socket來管理,下面是協議族層析的套接字結構體(BSD Socket)定義:

         

         

        1. /** 
        2.  *  struct socket - general BSD socket 
        3.  *  @state: socket state (%SS_CONNECTED, etc) 
        4.  *  @type: socket type (%SOCK_STREAM, etc) 
        5.  *  @flags: socket flags (%SOCK_ASYNC_NOSPACE, etc) 
        6.  *  @ops: protocol specific socket operations 
        7.  *  @file: File back pointer for gc 
        8.  *  @sk: internal networking protocol agnostic socket representation 
        9.  *  @wq: wait queue for several uses 
        10.  */  
        11. struct socket {  
        12.     socket_state        state;  
        13.   
        14.     kmemcheck_bitfield_begin(type);  
        15.     short           type;  
        16.     kmemcheck_bitfield_end(type);  
        17.   
        18.     unsigned long       flags;  
        19.   
        20.     struct socket_wq __rcu  *wq;  
        21.   
        22.     struct file     *file;  
        23.     struct sock     *sk;  
        24.     const struct proto_ops  *ops;  
        25. };  

        最后一個屬性就指向了上面所述的操作集。若使用TCP協議,ops就是inet_stream_ops,若是UDP協議,ops就是inet_dgram_ops。

        short type屬性的取值可以是如下值:

         

        1. enum sock_type {  
        2.     SOCK_DGRAM  = 1,  
        3.     SOCK_STREAM = 2,  
        4.     SOCK_RAW    = 3,  
        5.     SOCK_RDM    = 4,  
        6.     SOCK_SEQPACKET  = 5,  
        7.     SOCK_DCCP   = 6,  
        8.     SOCK_PACKET = 10,  
        9. };  

         

         

        傳輸層的協議操作集結構體定義:

         

        1. struct proto {  
        2.     void            (*close)(struct sock *sk,   
        3.                     long timeout);  
        4.     int         (*connect)(struct sock *sk,  
        5.                         struct sockaddr *uaddr,   
        6.                     int addr_len);  
        7.     int         (*disconnect)(struct sock *sk, int flags);  
        8.   
        9.     struct sock *       (*accept) (struct sock *sk, int flags, int *err);  
        10.   
        11.     int         (*ioctl)(struct sock *sk, int cmd,  
        12.                      unsigned long arg);  
        13.     int         (*init)(struct sock *sk);  
        14.     void            (*destroy)(struct sock *sk);  
        15.     void            (*shutdown)(struct sock *sk, int how);  
        16.     int         (*setsockopt)(struct sock *sk, int level,   
        17.                     int optname, char __user *optval,  
        18.                     unsigned int optlen);  
        19.     int         (*getsockopt)(struct sock *sk, int level,   
        20.                     int optname, char __user *optval,   
        21.                     int __user *option);       
        22. #ifdef CONFIG_COMPAT   
        23.     int         (*compat_setsockopt)(struct sock *sk,  
        24.                     int level,  
        25.                     int optname, char __user *optval,  
        26.                     unsigned int optlen);  
        27.     int         (*compat_getsockopt)(struct sock *sk,  
        28.                     int level,  
        29.                     int optname, char __user *optval,  
        30.                     int __user *option);  
        31.     int         (*compat_ioctl)(struct sock *sk,  
        32.                     unsigned int cmd, unsigned long arg);  
        33. #endif   
        34.     int         (*sendmsg)(struct kiocb *iocb, struct sock *sk,  
        35.                        struct msghdr *msg, size_t len);  
        36.     int         (*recvmsg)(struct kiocb *iocb, struct sock *sk,  
        37.                        struct msghdr *msg,  
        38.                     size_t len, int noblock, int flags,   
        39.                     int *addr_len);  
        40.     int         (*sendpage)(struct sock *sk, struct page *page,  
        41.                     int offset, size_t size, int flags);  
        42.     int         (*bind)(struct sock *sk,   
        43.                     struct sockaddr *uaddr, int addr_len);  
        44.   
        45.     int         (*backlog_rcv) (struct sock *sk,   
        46.                         struct sk_buff *skb);  
        47.   
        48.     /* Keeping track of sk's, looking them up, and port selection methods. */  
        49.     void            (*hash)(struct sock *sk);  
        50.     void            (*unhash)(struct sock *sk);  
        51.     void            (*rehash)(struct sock *sk);  
        52.     int         (*get_port)(struct sock *sk, unsigned short snum);  
        53.     void            (*clear_sk)(struct sock *sk, int size);  
        54.   
        55.     /* Keeping track of sockets in use */  
        56. #ifdef CONFIG_PROC_FS   
        57.     unsigned int        inuse_idx;  
        58. #endif   
        59.   
        60.     /* Memory pressure */  
        61.     void            (*enter_memory_pressure)(struct sock *sk);  
        62.     atomic_long_t       *memory_allocated;  /* Current allocated memory. */  
        63.     struct percpu_counter   *sockets_allocated; /* Current number of sockets. */  
        64.     /* 
        65.      * Pressure flag: try to collapse. 
        66.      * Technical note: it is used by multiple contexts non atomically. 
        67.      * All the __sk_mem_schedule() is of this nature: accounting 
        68.      * is strict, actions are advisory and have some latency. 
        69.      */  
        70.     int         *memory_pressure;  
        71.     long            *sysctl_mem;  
        72.     int         *sysctl_wmem;  
        73.     int         *sysctl_rmem;  
        74.     int         max_header;  
        75.     bool            no_autobind;  
        76.   
        77.     struct kmem_cache   *slab;  
        78.     unsigned int        obj_size;  
        79.     int         slab_flags;  
        80.   
        81.     struct percpu_counter   *orphan_count;  
        82.   
        83.     struct request_sock_ops *rsk_prot;  
        84.     struct timewait_sock_ops *twsk_prot;  
        85.   
        86.     union {  
        87.         struct inet_hashinfo    *hashinfo;  
        88.         struct udp_table    *udp_table;  
        89.         struct raw_hashinfo *raw_hash;  
        90.     } h;  
        91.   
        92.     struct module       *owner;  
        93.   
        94.     char            name[32];  
        95.   
        96.     struct list_head    node;  
        97. #ifdef SOCK_REFCNT_DEBUG   
        98.     atomic_t        socks;  
        99. #endif   
        100. };  
        該結構體和proto_ops的區別是:該結構體和具體的傳輸層協議相關,其中的函數指針指向對應的協議的相應的操作函數。

         


         

        TCP協議的操作集定義如下:

         

        1. struct proto tcp_prot = {  
        2.     .name           = "TCP",  
        3.     .owner          = THIS_MODULE,  
        4.     .close          = tcp_close,  
        5.     .connect        = tcp_v4_connect,  
        6.     .disconnect     = tcp_disconnect,  
        7.     .accept         = inet_csk_accept,  
        8.     .ioctl          = tcp_ioctl,  
        9.     .init           = tcp_v4_init_sock,  
        10.     .destroy        = tcp_v4_destroy_sock,  
        11.     .shutdown       = tcp_shutdown,  
        12.     .setsockopt     = tcp_setsockopt,  
        13.     .getsockopt     = tcp_getsockopt,  
        14.     .recvmsg        = tcp_recvmsg,  
        15.     .sendmsg        = tcp_sendmsg,  
        16.     .sendpage       = tcp_sendpage,  
        17.     .backlog_rcv        = tcp_v4_do_rcv,  
        18.     .hash           = inet_hash,  
        19.     .unhash         = inet_unhash,  
        20.     .get_port       = inet_csk_get_port,  
        21.     .enter_memory_pressure  = tcp_enter_memory_pressure,  
        22.     .sockets_allocated  = &tcp_sockets_allocated,  
        23.     .orphan_count       = &tcp_orphan_count,  
        24.     .memory_allocated   = &tcp_memory_allocated,  
        25.     .memory_pressure    = &tcp_memory_pressure,  
        26.     .sysctl_mem     = sysctl_tcp_mem,  
        27.     .sysctl_wmem        = sysctl_tcp_wmem,  
        28.     .sysctl_rmem        = sysctl_tcp_rmem,  
        29.     .max_header     = MAX_TCP_HEADER,  
        30.     .obj_size       = sizeof(struct tcp_sock),  
        31.     .slab_flags     = SLAB_DESTROY_BY_RCU,  
        32.     .twsk_prot      = &tcp_timewait_sock_ops,  
        33.     .rsk_prot       = &tcp_request_sock_ops,  
        34.     .h.hashinfo     = &tcp_hashinfo,  
        35.     .no_autobind        = true,  
        36. #ifdef CONFIG_COMPAT   
        37.     .compat_setsockopt  = compat_tcp_setsockopt,  
        38.     .compat_getsockopt  = compat_tcp_getsockopt,  
        39. #endif   
        40. };  

         


         

        UDP協議的操作集則為:

         

        1. struct proto udp_prot = {  
        2.     .name          = "UDP",  
        3.     .owner         = THIS_MODULE,  
        4.     .close         = udp_lib_close,  
        5.     .connect       = ip4_datagram_connect,  
        6.     .disconnect    = udp_disconnect,  
        7.     .ioctl         = udp_ioctl,  
        8.     .destroy       = udp_destroy_sock,  
        9.     .setsockopt    = udp_setsockopt,  
        10.     .getsockopt    = udp_getsockopt,  
        11.     .sendmsg       = udp_sendmsg,  
        12.     .recvmsg       = udp_recvmsg,  
        13.     .sendpage      = udp_sendpage,  
        14.     .backlog_rcv       = __udp_queue_rcv_skb,  
        15.     .hash          = udp_lib_hash,  
        16.     .unhash        = udp_lib_unhash,  
        17.     .rehash        = udp_v4_rehash,  
        18.     .get_port      = udp_v4_get_port,  
        19.     .memory_allocated  = &udp_memory_allocated,  
        20.     .sysctl_mem    = sysctl_udp_mem,  
        21.     .sysctl_wmem       = &sysctl_udp_wmem_min,  
        22.     .sysctl_rmem       = &sysctl_udp_rmem_min,  
        23.     .obj_size      = sizeof(struct udp_sock),  
        24.     .slab_flags    = SLAB_DESTROY_BY_RCU,  
        25.     .h.udp_table       = &udp_table,  
        26. #ifdef CONFIG_COMPAT   
        27.     .compat_setsockopt = compat_udp_setsockopt,  
        28.     .compat_getsockopt = compat_udp_getsockopt,  
        29. #endif   
        30.     .clear_sk      = sk_prot_clear_portaddr_nulls,  
        31. };  


         

        現在介紹struct socket結構體中一個屬性struct sock類型的結構體指針,這個結構體就是傳輸層的套接字,所有套接字通過該結構來使用網絡協議的所有服務。定義如下:

         

        1. struct sock {  
        2.     /* 
        3.      * Now struct inet_timewait_sock also uses sock_common, so please just 
        4.      * don't add nothing before this first member (__sk_common) --acme 
        5.      */  
        6.     struct sock_common  __sk_common;  
        7. #define sk_node         __sk_common.skc_node   
        8. #define sk_nulls_node       __sk_common.skc_nulls_node   
        9. #define sk_refcnt       __sk_common.skc_refcnt   
        10. #define sk_tx_queue_mapping __sk_common.skc_tx_queue_mapping   
        11.   
        12. #define sk_dontcopy_begin   __sk_common.skc_dontcopy_begin   
        13. #define sk_dontcopy_end     __sk_common.skc_dontcopy_end   
        14. #define sk_hash         __sk_common.skc_hash   
        15. #define sk_family       __sk_common.skc_family   
        16. #define sk_state        __sk_common.skc_state   
        17. #define sk_reuse        __sk_common.skc_reuse   
        18. #define sk_bound_dev_if     __sk_common.skc_bound_dev_if   
        19. #define sk_bind_node        __sk_common.skc_bind_node   
        20. #define sk_prot         __sk_common.skc_prot   
        21. #define sk_net          __sk_common.skc_net   
        22.     socket_lock_t       sk_lock;  
        23.     struct sk_buff_head sk_receive_queue;  
        24.     /* 
        25.      * The backlog queue is special, it is always used with 
        26.      * the per-socket spinlock held and requires low latency 
        27.      * access. Therefore we special case it's implementation. 
        28.      * Note : rmem_alloc is in this structure to fill a hole 
        29.      * on 64bit arches, not because its logically part of 
        30.      * backlog. 
        31.      */  
        32.     struct {  
        33.         atomic_t    rmem_alloc;  
        34.         int     len;  
        35.         struct sk_buff  *head;  
        36.         struct sk_buff  *tail;  
        37.     } sk_backlog;  
        38. #define sk_rmem_alloc sk_backlog.rmem_alloc   
        39.     int         sk_forward_alloc;  
        40. #ifdef CONFIG_RPS   
        41.     __u32           sk_rxhash;  
        42. #endif   
        43.     atomic_t        sk_drops;  
        44.     int         sk_rcvbuf;  
        45.   
        46.     struct sk_filter __rcu  *sk_filter;  
        47.     struct socket_wq __rcu  *sk_wq;  
        48.   
        49. #ifdef CONFIG_NET_DMA   
        50.     struct sk_buff_head sk_async_wait_queue;  
        51. #endif   
        52.   
        53. #ifdef CONFIG_XFRM   
        54.     struct xfrm_policy  *sk_policy[2];  
        55. #endif   
        56.     unsigned long       sk_flags;  
        57.     struct dst_entry    *sk_dst_cache;  
        58.     spinlock_t      sk_dst_lock;  
        59.     atomic_t        sk_wmem_alloc;  
        60.     atomic_t        sk_omem_alloc;  
        61.     int         sk_sndbuf;  
        62.     struct sk_buff_head sk_write_queue;  
        63.     kmemcheck_bitfield_begin(flags);  
        64.     unsigned int        sk_shutdown  : 2,  
        65.                 sk_no_check  : 2,  
        66.                 sk_userlocks : 4,  
        67.                 sk_protocol  : 8,  
        68.                 sk_type      : 16;  
        69.     kmemcheck_bitfield_end(flags);  
        70.     int         sk_wmem_queued;  
        71.     gfp_t           sk_allocation;  
        72.     int         sk_route_caps;  
        73.     int         sk_route_nocaps;  
        74.     int         sk_gso_type;  
        75.     unsigned int        sk_gso_max_size;  
        76.     int         sk_rcvlowat;  
        77.     unsigned long           sk_lingertime;  
        78.     struct sk_buff_head sk_error_queue;  
        79.     struct proto        *sk_prot_creator;  
        80.     rwlock_t        sk_callback_lock;  
        81.     int         sk_err,  
        82.                 sk_err_soft;  
        83.     unsigned short      sk_ack_backlog;  
        84.     unsigned short      sk_max_ack_backlog;  
        85.     __u32           sk_priority;  
        86.     struct pid      *sk_peer_pid;  
        87.     const struct cred   *sk_peer_cred;  
        88.     long            sk_rcvtimeo;  
        89.     long            sk_sndtimeo;  
        90.     void            *sk_protinfo;  
        91.     struct timer_list   sk_timer;  
        92.     ktime_t         sk_stamp;  
        93.     struct socket       *sk_socket;  
        94.     void            *sk_user_data;  
        95.     struct page     *sk_sndmsg_page;  
        96.     struct sk_buff      *sk_send_head;  
        97.     __u32           sk_sndmsg_off;  
        98.     int         sk_write_pending;  
        99. #ifdef CONFIG_SECURITY   
        100.     void            *sk_security;  
        101. #endif   
        102.     __u32           sk_mark;  
        103.     u32         sk_classid;  
        104.     void            (*sk_state_change)(struct sock *sk);  
        105.     void            (*sk_data_ready)(struct sock *sk, int bytes);  
        106.     void            (*sk_write_space)(struct sock *sk);  
        107.     void            (*sk_error_report)(struct sock *sk);  
        108.     int         (*sk_backlog_rcv)(struct sock *sk,  
        109.                           struct sk_buff *skb);    
        110.     void                    (*sk_destruct)(struct sock *sk);  
        111. };  
        若sk_family是PF_INET,則sk_type可以取值:SOCK_STREAM,SOCK_DGRAM,SOCK_RAW。其中sk_prot就是指向具體協議的操作集,如TCP協議就為tcp_prot。

         

        若要將協議族操作集和具體協議操作集整合起來為IP協議提供接口,就需要下面的結構體定義:

         

        1. struct inet_protosw {  
        2.     struct list_head list;  
        3.   
        4.         /* These two fields form the lookup key.  */  
        5.     unsigned short   type;     /* This is the 2nd argument to socket(2). */  
        6.     unsigned short   protocol; /* This is the L4 protocol number.  */  
        7.   
        8.     struct proto     *prot;  
        9.     const struct proto_ops *ops;  
        10.     
        11.     char             no_check;   /* checksum on rcv/xmit/none? */  
        12.     unsigned char    flags;      /* See INET_PROTOSW_* below.  */  
        13. };  

        INET三種套接字定義的inetsw_array數組如下:

         

         

        1. static struct inet_protosw inetsw_array[] =  
        2. {  
        3.     {  
        4.         .type =       SOCK_STREAM,  
        5.         .protocol =   IPPROTO_TCP,  
        6.         .prot =       &tcp_prot,  
        7.         .ops =        &inet_stream_ops,  
        8.         .no_check =   0,  
        9.         .flags =      INET_PROTOSW_PERMANENT |  
        10.                   INET_PROTOSW_ICSK,  
        11.     },  
        12.   
        13.     {  
        14.         .type =       SOCK_DGRAM,  
        15.         .protocol =   IPPROTO_UDP,  
        16.         .prot =       &udp_prot,  
        17.         .ops =        &inet_dgram_ops,  
        18.         .no_check =   UDP_CSUM_DEFAULT,  
        19.         .flags =      INET_PROTOSW_PERMANENT,  
        20.        },  
        21.   
        22.        {  
        23.         .type =       SOCK_DGRAM,  
        24.         .protocol =   IPPROTO_ICMP,  
        25.         .prot =       &ping_prot,  
        26.         .ops =        &inet_dgram_ops,  
        27.         .no_check =   UDP_CSUM_DEFAULT,  
        28.         .flags =      INET_PROTOSW_REUSE,  
        29.        },  
        30.   
        31.        {  
        32.            .type =       SOCK_RAW,  
        33.            .protocol =   IPPROTO_IP,    /* wild card */  
        34.            .prot =       &raw_prot,  
        35.            .ops =        &inet_sockraw_ops,  
        36.            .no_check =   UDP_CSUM_DEFAULT,  
        37.            .flags =      INET_PROTOSW_REUSE,  
        38.        }  
        39. };  
        不過,在初始化的時候我們會將上面數組中的的元素按套接字類型插入inetsw鏈表數組中。其定義如下:

         

         

        1. static struct list_head inetsw[SOCK_MAX];  

         


         

        下篇將分析套接字的操作函數。

        億恩-天使(530997) 電話 037160135991 服務器租用,托管歡迎咨詢

        本文出自:億恩科技【www.endtimedelusion.com】

        服務器租用/服務器托管中國五強!虛擬主機域名注冊頂級提供商!15年品質保障!--億恩科技[ENKJ.COM]

      1. 您可能在找
      2. 億恩北京公司:
      3. 經營性ICP/ISP證:京B2-20150015
      4. 億恩鄭州公司:
      5. 經營性ICP/ISP/IDC證:豫B1.B2-20060070
      6. 億恩南昌公司:
      7. 經營性ICP/ISP證:贛B2-20080012
      8. 服務器/云主機 24小時售后服務電話:0371-60135900
      9. 虛擬主機/智能建站 24小時售后服務電話:0371-60135900
      10. 專注服務器托管17年
        掃掃關注-微信公眾號
        0371-60135900
        Copyright© 1999-2019 ENKJ All Rights Reserved 億恩科技 版權所有  地址:鄭州市高新區翠竹街1號總部企業基地億恩大廈  法律顧問:河南亞太人律師事務所郝建鋒、杜慧月律師   京公網安備41019702002023號
          0
         
         
         
         

        0371-60135900
        7*24小時客服服務熱線

         
         
        av不卡不卡在线观看_最近2018年中文字幕_亚洲欧美一区二区三区_一级A爱做片免费观看国产_日韩在线中文天天更新_伊人中文无码在线