• Linux 网络之ss


    前言

    ss工具和netstat工具的功能相似,当是更加高效,ss属于iproute2 package,这个包的工具还有 ss、ip、和 nstat 等等,此软件包中的工具最有可能支持最新的 Linux 内核功能,因此推荐用ss取代netstat。
    即用 iproute2 package取代net-tools package。

    关于netstat请参考:Linux 网络之netstat

    一、ss简单使用

    由于ss和netstat使用相似,列出其选项:

     ss is used to dump socket statistics
    
    • 1
     -b, --bpf
            Show socket BPF filters 
    
     -4, --ipv4
            Display only IP version 4 sockets (alias for -f inet).
    
     -6, --ipv6
            Display only IP version 6 sockets (alias for -f inet6).
    
     -0, --packet
            Display PACKET sockets (alias for -f link).
    
     -t, --tcp
            Display TCP sockets.
    
     -u, --udp
            Display UDP sockets.
    
     -d, --dccp
            Display DCCP sockets.
    
     -w, --raw
            Display RAW sockets.
    
     -x, --unix
            Display Unix domain sockets (alias for -f unix).
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
     -l, --listening
            Display only listening sockets (these are omitted by default).
    
     -o, --options
            Show timer information.
    
     -e, --extended
            Show detailed socket information
    
     -m, --memory
            Show socket memory usage.
    
     -p, --processes
            Show process using socket.
    
     -i, --info
            Show internal TCP information.
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    二、ss详细输出说明

    在使用选项时,ss 相比 netstat 可以显示更多信息。 例如,仅显示 TCP 套接字 (-t)、TCP 内部信息 (-i)、扩展套接字信息 (-e)、进程信息 (-p) 和内存使用 (-m):

    [root@localhost ~]# ss -tiepm
    State      Recv-Q Send-Q                Local Address:Port   		Peer Address:Port                                    
    ESTAB      0      112                   xx.xx.xx.xxx:ssh     		xx.xx.xx.xx:xxxxx       
                                                                                    
    users:(("sshd",pid=1608,fd=3)) timer:(on,242ms,0) ino:134147 sk:ffff9f1d0ae7ae80 <->
             ......rto:242 rtt:41.707/6.808  mss:1460  cwnd:10 bytes_acked:5069 bytes_received:3836 pacing_rate 5.6Mbps 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    其中一些字段说明:

     "sshd",pid=1608 : Process name "sshd", PID 1608.
     fd=3: File descriptor 3 (for PID 1608).
     ino:134147: socket inode : 134147
     rto:242: TCP retransmission timeout: 242 milliseconds.
     rtt:41.707/6.808: Average round-trip time is 41.707 milliseconds, with 6.808 milliseconds 
    mean deviation.
     mss:1460: Maximum segment size: 1460 bytes.
     cwnd:10: Congestion window size: 10 × MSS.
     bytes_acked:5069: 5069 bytes successfully transmitted.
     bytes_received:3836: 3836 bytes received.
     pacing_rate 5.6Mbps: Pacing rate of 5.6 Mbps.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    其中sk:ffff9f1d0ae7ae80,代表该tcp 连接 struct sock结构体的起始地址,我们可以用crash查看:

    crash> sock ffff9f1d0ae7ae80
    struct sock {
    	......
    	skc_family = 2,
        skc_state = 1 '\001',
    	......
      	sk_protocol = 6,
      	sk_type = 1,
    	......
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    struct sock :套接字的网络层表示结构体。

    // linux-3.10/include/net/sock.h
    
    /* struct sock - network layer representation of sockets */
    struct sock {
    	/*
    	 * Now struct inet_timewait_sock also uses sock_common, so please just
    	 * don't add nothing before this first member (__sk_common) --acme
    	 */
    	struct sock_common	__sk_common;
    #define sk_family		__sk_common.skc_family
    #define sk_state		__sk_common.skc_state
    
    	......
    
    	unsigned int		sk_shutdown  : 2,
    			......
    			sk_protocol  : 8,
    			sk_type      : 16;
    	
    	......
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    对于TCP struct sock sk :

    sk. skc_family = 2

    // linux-3.10/include/linux/socket.h
    
    /* Supported address families. */
    #define AF_UNIX		1	/* Unix domain sockets 		*/
    #define AF_LOCAL	1	/* POSIX name for AF_UNIX	*/
    #define AF_INET		2	/* Internet IP Protocol 	*/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    sk.sk_state = 1
    sk_state表示该TCP连接当前的连接状态

    // linux-3.10/include/net/tcp_states.h
    
    /*
     * INET		An implementation of the TCP/IP protocol suite for the LINUX
     *		operating system.  INET is implemented using the  BSD Socket
     *		interface as the means of communication with the user level.
     *
     *		Definitions for the TCP protocol sk_state field.
     *
     */
    #ifndef _LINUX_TCP_STATES_H
    #define _LINUX_TCP_STATES_H
    
    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,	/* Now a valid state */
    
    	TCP_MAX_STATES	/* Leave at the end! */
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    sk.sk_type = 1
    type就是socket的类型,对于AF_INET协议族而言有流套接字(SOCK_STREAM)、数据包套接字(SOCK_DGRAM)、原始套接字(SOCK_RAW)

    // linux-3.10/include/linux/net.h
    
    /**
     * enum sock_type - Socket types
     * @SOCK_STREAM: stream (connection) socket
     * @SOCK_DGRAM: datagram (conn.less) socket
     * @SOCK_RAW: raw socket
     * @SOCK_RDM: reliably-delivered message
     * @SOCK_SEQPACKET: sequential packet socket
     * @SOCK_DCCP: Datagram Congestion Control Protocol socket
     * @SOCK_PACKET: linux specific way of getting packets at the dev level.
     *		  For writing rarp and other similar things on the user level.
     *
     * When adding some new socket type please
     * grep ARCH_HAS_SOCKET_TYPE include/asm-* /socket.h, at least MIPS
     * overrides this enum for binary compat reasons.
     */
    enum sock_type {
    	SOCK_STREAM	= 1,
    	SOCK_DGRAM	= 2,
    	SOCK_RAW	= 3,
    	SOCK_RDM	= 4,
    	SOCK_SEQPACKET	= 5,
    	SOCK_DCCP	= 6,
    	SOCK_PACKET	= 10,
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    sk.sk_protocol = 6

    // linux-3.10/include/uapi/linux/in.h
    
    /*
     * INET		An implementation of the TCP/IP protocol suite for the LINUX
     *		operating system.  INET is implemented using the  BSD Socket
     *		interface as the means of communication with the user level.
     *
     *		Definitions of the Internet Protocol.
     */
    
    /* Standard well-defined IP protocols.  */
    enum {
      IPPROTO_IP = 0,		/* Dummy protocol for TCP		*/
      IPPROTO_ICMP = 1,		/* Internet Control Message Protocol	*/
      IPPROTO_IGMP = 2,		/* Internet Group Management Protocol	*/
      IPPROTO_IPIP = 4,		/* IPIP tunnels (older KA9Q tunnels use 94) */
      IPPROTO_TCP = 6,		/* Transmission Control Protocol	*/
      IPPROTO_EGP = 8,		/* Exterior Gateway Protocol		*/
      IPPROTO_PUP = 12,		/* PUP protocol				*/
      IPPROTO_UDP = 17,		/* User Datagram Protocol		*/
      IPPROTO_IDP = 22,		/* XNS IDP protocol			*/
      IPPROTO_DCCP = 33,		/* Datagram Congestion Control Protocol */
      IPPROTO_RSVP = 46,		/* RSVP protocol			*/
      IPPROTO_GRE = 47,		/* Cisco GRE tunnels (rfc 1701,1702)	*/
    
      IPPROTO_IPV6	 = 41,		/* IPv6-in-IPv4 tunnelling		*/
    
      IPPROTO_ESP = 50,            /* Encapsulation Security Payload protocol */
      IPPROTO_AH = 51,             /* Authentication Header protocol       */
      IPPROTO_BEETPH = 94,	       /* IP option pseudo header for BEET */
      IPPROTO_PIM    = 103,		/* Protocol Independent Multicast	*/
    
      IPPROTO_COMP   = 108,                /* Compression Header protocol */
      IPPROTO_SCTP   = 132,		/* Stream Control Transport Protocol	*/
      IPPROTO_UDPLITE = 136,	/* UDP-Lite (RFC 3828)			*/
    
      IPPROTO_RAW	 = 255,		/* Raw IP packets			*/
      IPPROTO_MAX
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    上述输出中缺少的一个细节是连接的时间,这是计算平均吞吐量所必需的。 可以在 /proc 中的文件描述符文件上使用 the change timestamp:对于此连接,将在 /proc/1608/fd/3 上运行 stat:

    [root@localhost ~]# stat /proc/1608/fd/3
      File:/proc/1608/fd/3-> ‘socket:[134147]’
      Size: 64              Blocks: 0          IO Block: 1024   symbolic link
    Device: 3h/3d   Inode: 133169      Links: 1
    Access: (xxx/lxxxxxxxxx)  Uid: (    x/    xxx)   Gid: (    x/    xxx)
    Context: unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
    Access: 2022-10-28 10:19:58.728134501 +0800
    Modify: 2022-10-28 09:50:45.580537840 +0800
    Change: 2022-10-28 09:50:45.580537840 +0800
     Birth: -
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    三、ss数据来源

    ss 从 netlink 接口读取这些扩展细节,该接口通过 AF_NETLINK 系列的套接字操作以从内核获取信息。

    netlink 是一个特殊的套接字地址族(AF_NETLINK),用于获取内核信息。使用netlink需要打开一个带有AF_NETLINK地址族的网络套接字,然后使用一系列 send 和 recv 调用以二进制结构传递请求和接收信息。 虽然这是一个比 /proc 更复杂的接口,但它更高效,并且还支持通知机制。

    // linux-3.10/include/linux/socket.h
    
    #define AF_NETLINK	16
    
    • 1
    • 2
    • 3

    使用strace跟踪ss -t命令执行过程中调用socket系统调用(-e socket 字面意思是 -e trace= socket ,这意味着只跟踪 socket 系统调用):

    [root@localhost ~]# strace -e socket ss -t
    State      Recv-Q Send-Q                                                       Local Address:Port                                                                        Peer Address:Port
    socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_SOCK_DIAG) = 3
    socket(AF_LOCAL, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 5
    socket(AF_LOCAL, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 5
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这是为 the group NETLINK_SOCK_DIAG 打开一个AF_NETLINK套接字,它返回关于套接字的信息。

    netlink groups include:
     NETLINK_ROUTE: Route information (there is also /proc/net/route)
     NETLINK_SOCK_DIAG: Socket information
     NETLINK_SELINUX: SELinux event notifications
     NETLINK_AUDIT: Auditing (security)
     NETLINK_SCSITRANSPORT: SCSI transports
     NETLINK_CRYPTO: Kernel crypto information
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    跟踪ss -t执行过程中的sendmsg和recvmsg系统调用:

    strace -e sendmsg,recvmsg ss -t 2>ss_log
    cat ss_log | grep AF_NETLINK
    
    • 1
    • 2
    sendmsg(3, {msg_name(12)={sa_family=AF_NETLINK, ......})
    recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, ......})
    recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, ......})
    recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, ......})
    recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, ......})
    sendmsg(3, {msg_name(12)={sa_family=AF_NETLINK, ......})
    recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, ......})
    recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, ......})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    源码分析请参考:ss源代码调试&原理分析

    参考资料

    Linux 3.10

    Systems.Performance.Enterprise.and.the.Cloud.2nd.Edition

  • 相关阅读:
    【视频】马尔可夫链蒙特卡罗方法MCMC原理与R语言实现|数据分享
    PriorityQueue常用接口介绍
    mybatis-plus实现多租户Saas
    LearnOpenGL1.3:着色器
    Java发送httpPost,httpGet,httpDelete请求
    计算机毕业设计(附源码)python装修服务分析系统
    如何解决 Iterative 半监督训练 在 ASR 训练中难以落地的问题丨RTC Dev Meetup
    【Linux】线程
    HTML期末学生大作业 基于HTML+CSS+JavaScript通用的后台管理系统ui框架模板
    【Java】增强for循环
  • 原文地址:https://blog.csdn.net/weixin_45030965/article/details/127560679