發現一篇使用ss擷取TCP内部狀态資訊的好文,不由的記錄一筆。
并結合之前會的方法适當總結總結。
這種好文當然是推薦去讀原文了,這裡對文章中的方法隻做簡單摘要。
而這類相似方法還有哪些,以及各自的優缺點可以看看下一節的總結。
// 可檢視盡量多的顯示socket相關的内部資訊
# ss -eipn
Internally, ss uses the tcp_diag kernel module to extract
information (this is done via anAF_NETLINKsocket).
// 通過crash根據sk的記憶體位址,擷取更多的sk結構體item資訊
# sudo crash -e emacs
crash > struct tcp_sock.rcv_nxt,snd_una,reordering ffff8802305a0800
總結
目前掌握的擷取TCP内部狀态的方法,這裡讨論的方法都是不需要額外在核心中做開發的:
a. 使用tcp_probe核心子產品
改改tcp_probe幾乎可以擷取TCP内部的任何狀态
具體怎麼使用tcp_probe子產品,在之前的這篇部落格中有詳細的介紹。
優點(考慮适當自定制該子產品):
1. 功能性:可檢視TCP流的幾乎所有的内部狀态
2. 靈活性:定制一次必須重編一次子產品
缺點:
1. 功能性:不适合線上裝置使用,大量不同流的資訊混在一起簡直是災難(如何有效的使用過濾政策是一個好問題)
2. 可用性:如果沒有kernel-devel包,無法自定制編譯使用核心子產品
b. 使用systemtap腳本
優點:
1. 功能性:幾乎可以探測TCP流在任何處理邏輯(内聯函數是一個痛點)處的資訊
2. 靈活性:友善設定過濾政策,(相對tcp_probe而言)可友善的統計出想要的資訊。
不管是通過指定腳本參數,還是直接修改腳本,都比修改tcp_probe核心子產品友善
缺點:
1. 可用性:依賴kernel-devel, kernel-debuginfo, kernel-debuginfo-common包
而為了避免暴露自定制核心的内部實作,這些包預設都是不安裝的
c. ss+crash
如果隻需要ss預設支援的資訊,那這種方法當然是最佳的。
但可信的就是ss預設支援的資訊,還是太少,是以可能需要crash來補充
優點:
1. 功能性:在僅需要ss預設支援的資訊時,最實用。隻要安裝ss軟體即可
本質上ss輸出的資訊,是核心統計的,ss隻是一個輸出工具而已
缺點:
1. 功能性:受限于核心統計的資訊,受限與ss工具的選擇的輸出資訊
2. 可用性:如果試圖通過ss得到的sk記憶體位址,利用crash進一步獲得資訊,則需要核心image能找到。
這點線上上裝置上也顯然是不現實的
不過受ss+crash這種方法的啟發,既然能拿到sk結構體的記憶體位址,有沒有更簡單,
友善的方法來擷取sk内部item的值呢?
如果大家有更好的方法,非常歡迎留言交流。