文章目录
- 前言
- 一、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 评论