Linux 网络之ss

文章目录

  • 前言
  • 一、ss简单使用
  • 二、ss详细输出说明
  • 三、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
 -b, --bpfShow socket BPF filters -4, --ipv4Display only IP version 4 sockets (alias for -f inet).-6, --ipv6Display only IP version 6 sockets (alias for -f inet6).-0, --packetDisplay PACKET sockets (alias for -f link).-t, --tcpDisplay TCP sockets.-u, --udpDisplay UDP sockets.-d, --dccpDisplay DCCP sockets.-w, --rawDisplay RAW sockets.-x, --unixDisplay Unix domain sockets (alias for -f unix).
 -l, --listeningDisplay only listening sockets (these are omitted by default).-o, --optionsShow timer information.-e, --extendedShow detailed socket information-m, --memoryShow socket memory usage.-p, --processesShow process using socket.-i, --infoShow internal TCP information.

二、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 

其中一些字段说明:

 "sshd",pid=1608 : Process name "sshd", PID 1608.fd=3: File descriptor 3 (for PID 1608).ino:134147: socket inode : 134147rto: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.

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

crash> sock ffff9f1d0ae7ae80
struct sock {......skc_family = 2,skc_state = 1 '\001',......sk_protocol = 6,sk_type = 1,......
}

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;......
}

对于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 	*/

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_Henum {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! */
};

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,
};

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
};

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

[root@localhost ~]# stat /proc/1608/fd/3File:/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 +0800Birth: -

三、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

使用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

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

netlink groups include:NETLINK_ROUTE: Route information (there is also /proc/net/route)NETLINK_SOCK_DIAG: Socket informationNETLINK_SELINUX: SELinux event notificationsNETLINK_AUDIT: Auditing (security)NETLINK_SCSITRANSPORT: SCSI transportsNETLINK_CRYPTO: Kernel crypto information

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

strace -e sendmsg,recvmsg ss -t 2>ss_log
cat ss_log | grep 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, ......})
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, ......})

参考资料

Linux 3.10

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

本文链接:https://my.lmcjl.com/post/1124.html

展开阅读全文

4 评论

留下您的评论.