這篇文章主要介紹linux中Packetdrill如何使用,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
創(chuàng)新互聯(lián)公司網(wǎng)站建設(shè)由有經(jīng)驗的網(wǎng)站設(shè)計師、開發(fā)人員和項目經(jīng)理組成的專業(yè)建站團隊,負責(zé)網(wǎng)站視覺設(shè)計、用戶體驗優(yōu)化、交互設(shè)計和前端開發(fā)等方面的工作,以確保網(wǎng)站外觀精美、網(wǎng)站制作、成都網(wǎng)站建設(shè)易于使用并且具有良好的響應(yīng)性。
1. Packetdrill 編譯與安裝
源碼鏈接 https://github.com/google/packetdrill.git
源碼編譯 注釋netdev.c
/* Set the offload flags to be like a typical ethernet device */ static void set_device_offload_flags(struct local_netdev *netdev) { #ifdef linux // const u32 offload = // TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 | TUN_F_TSO_ECN | TUN_F_UFO; // if (ioctl(netdev->tun_fd, TUNSETOFFLOAD, offload) != 0) // die_perror("TUNSETOFFLOAD"); #endif }
./configure && make
使用方法
./packetdrill test.pkt
test.pkt為按Packetdrill語法編寫的測試腳本。
成功:無輸出,表示腳本正確,一切都符合預(yù)期。
失?。褐赋瞿_本的錯誤地方,以及原因。
2. Packetdrill 執(zhí)行自帶測試用例
開啟tcpdump -i any tcp port 8080抓包便于分析
這里測試快速重傳,測試環(huán)境centos7.2。
簡單說明< 表示輸入,packetdrill會構(gòu)造一個真實的數(shù)據(jù)包。>表示預(yù)期協(xié)議棧會響應(yīng)的數(shù)據(jù)包。(這個包不是由packetdrill構(gòu)造的,而是由協(xié)議棧發(fā)出的。)
// Test fast retransmit with 4 packets outstanding, receiver sending SACKs. // In this variant the receiver supports SACK. // Establish a connection. 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 +0 bind(3, ..., ...) = 0 +0 listen(3, 1) = 0 //三次握手 +0 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 7> +0 > S. 0:0(0) ack 1 <...> +.1 < . 1:1(0) ack 1 win 257 +0 accept(3, ..., ...) = 4 //系統(tǒng)調(diào)用,讓協(xié)議棧發(fā)出100個字節(jié) // Send 1 data segment and get an ACK, so cwnd is now 4. +0 write(4, ..., 1000) = 1000 //預(yù)期協(xié)議棧會發(fā)出psh,ack,實際上發(fā)出了ack1 //+0 > P. 1:1001(1000) ack 2 //向協(xié)議棧注入 ack +.1 < . 1:1(0) ack 1001 win 257 // Write 4 data segments. //系統(tǒng)調(diào)用,讓協(xié)議棧發(fā)出4000個字節(jié) +0 write(4, ..., 4000) = 4000 //預(yù)期協(xié)議棧會發(fā)出psh,ack,實際上發(fā)出了seq 1001:2001, ack 1;seq 2001:3001, ack 1;seq 3001:4001, ack 1;[P.], seq 4001:5001, ack 1 //+0 > P. 1001:5001(4000) ack 1 // Get 3 SACKs. //向協(xié)議棧連續(xù)發(fā)出三個ack +.1 < . 1:1(0) ack 1001 win 257 <sack 2001:3001,nop,nop> +0 < . 1:1(0) ack 1001 win 257 <sack 2001:4001,nop,nop> +0 < . 1:1(0) ack 1001 win 257 <sack 2001:5001,nop,nop> // We've received 3 duplicate ACKs, so we do a fast retransmit. //預(yù)期協(xié)議棧會發(fā)出一次快速重傳 Seq 1001:2001,ack 1 //+0 > . 1001:2001(1000) ack 1 // Receiver ACKs all data. //向協(xié)議棧ack,響應(yīng)所有報文的ack。 +.1 < . 1:1(0) ack 6001 win 257 4. 將fr-4pkt-sack-linux.pkt 中的修改如下。 +0 > P. 1:1001(1000) ack 2 ? +0 > P. 1:1001(1000) ack 1 //+0 > P. 1001:5001(4000) ack 1 ? +0 > . 1001:2001(1000) ack 1 +0 > . 2001:3001(1000) ack 1 +0 > . 3001:4001(1000) ack 1 +0 > P. 4001:5001(1000) ack 1
[注解:如果執(zhí)行packetdrill自帶的用例出錯,一般是協(xié)議棧發(fā)出的包沒有達到預(yù)期的包,先將預(yù)期>那部分干掉,然后再執(zhí)行測試用例,然后通過抓包分析預(yù)期結(jié)果。通常是因為三次握手mss 的限制]
執(zhí)行: ../../../packetdrill fr-4pkt-sack-linux.pkt,無出錯。
抓包可以看到一下結(jié)果:三次重復(fù)ack,則實施快速重傳。達到預(yù)期效果。
// 自己構(gòu)造包實現(xiàn)三次重復(fù)的ack 1001. 07:57:36.469280 IP 192.0.2.1.36840 > TENCENT64.site.webcache: Flags [.], ack 1001, win 257, options [sack 1 {2001:3001},nop,nop], length 0 07:57:36.469836 IP 192.0.2.1.36840 > TENCENT64.site.webcache: Flags [.], ack 1001, win 257, options [sack 1 {2001:4001},nop,nop], length 0 07:57:36.470349 IP 192.0.2.1.36840 > TENCENT64.site.webcache: Flags [.], ack 1001, win 257, options [sack 1 {2001:5001},nop,nop], length 0 // 協(xié)議棧發(fā)起快速重傳。Seq 1001:2001,ack 1,1000 07:57:36.470376 IP TENCENT64.site.webcache > 192.0.2.1.36840: Flags [.], seq 1001:2001, ack 1, win 229, length 1000
3. Packetdrill 解讀自帶測試用例說明
這里主要說明packetdrill的基本語法。
腳本中可以包含四種語句:數(shù)據(jù)包、系統(tǒng)調(diào)用、shell命令、python語句。
每條語句都必須以時間戳開頭,指明它的執(zhí)行時間。
Packets
數(shù)據(jù)包分為:輸入的數(shù)據(jù)包、輸出的數(shù)據(jù)包,格式類似于tcpdump的,
支持TCP、UDP、ICMP,以及TCP的大部分選項。
輸入數(shù)據(jù)包(<表示輸入):packetdrill會構(gòu)造一個真實的數(shù)據(jù)包,然后注入?yún)f(xié)議棧。
例子:
0.100 < S 0:0(0) win 32792 <mss 1000, nop, nop, sackOK, nop, wscale 7> 0.250 < [1:1461(1460)] icmp unreachable frag_needed mtu 1200
輸出數(shù)據(jù)包(>表示輸出):packetdrill會檢查協(xié)議棧是不是真的發(fā)出了這樣一個包。
+0 > udp (1472)
System Calls
系統(tǒng)調(diào)用的格式類似于strace。
對于每個系統(tǒng)調(diào)用,packetdrill會在指定的時間給予執(zhí)行,并檢查返回值是否和預(yù)期的一樣。系統(tǒng)調(diào)用的主要是應(yīng)用于場景構(gòu)造,已經(jīng)非測試端的數(shù)據(jù)發(fā)送和接收。
常見的系統(tǒng)調(diào)用例子:
系統(tǒng)調(diào)用
connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress) //客戶端連接服務(wù)器 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0 //獲取scoketopt fcntl(3, F_SETFL, O_RDWR) = 0 //Fcntl設(shè)置 ioctl(4, SIOCINQ, [1000]) = 0 //Ioctl設(shè)置 read(3, ..., 1024) = 785 //讀取數(shù)據(jù) write(3, ..., 57) = 57 //寫入數(shù)據(jù) close(3) = 0 //關(guān)閉連接 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 //Tcp socket setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 //設(shè)置地址復(fù)用 bind(3, ..., ...) = 0 //綁定端口 listen(3, 1) = 0 //監(jiān)聽端口 accept(3, ..., ...) = 4 //接受連接
shell腳本用法
常見用法是用shell腳本設(shè)置內(nèi)核參數(shù)或者調(diào)用shell命令統(tǒng)計tcp信息。設(shè)置
例子:
+0 `sysctl -q net.ipv4.tcp_timestamps=0` +0 `ss -4 -n state SYN-RECV | grep 192.168.0.1:8080 > /dev/null`
python腳本的用法
常見用法是使用python的assert斷言tcp_info的里面的信息,是否符合預(yù)期。
例子:
0.310 %{ assert tcpi_reordering == 3 assert tcpi_unacked == 10 assert tcpi_sacked == 6 assert tcpi_ca_state == TCP_CA_Recovery }%
時間戳
每條語句都必須以時間戳開頭,指明它的執(zhí)行時間,或者預(yù)期事件的發(fā)生時間。測試case有可能是timing的問題導(dǎo)致測試case無法通過。
時間戳可以使用多種格式:
Absolute(絕對時間):0.75 Relative(相對時間):+0.2 Wildcard(任意時間):* Range(絕對時間區(qū)間):0.750~0.900 Relative Range(相對時間區(qū)間):+0.1~+0.2 Loose(允許誤差值):--tolerance_usecs=800 Blocking(阻塞時間區(qū)間):0.750...0.900
如果在規(guī)定的時間戳,對應(yīng)的事件并沒有發(fā)生就會報錯,并告知該事件的實際發(fā)生時間。
+1.0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 6>
預(yù)期在1s以后TCP應(yīng)該發(fā)送一個SYNACK包。
在實際的使用中,一般指定–tolerance_usecs=405000,也就是允許4ms的時間誤差。
4. Packetdrill 實現(xiàn)基本場景構(gòu)造測試
場景的場景構(gòu)造是客戶端場景或者是服務(wù)器場景。具體包怎么構(gòu)造,具體看packetdrill的自帶的測試用例。
1.服務(wù)端場景
構(gòu)造服務(wù)器端場景:數(shù)據(jù)包輸入端是客戶端。數(shù)據(jù)包輸出端是系統(tǒng)調(diào)用,充當(dāng)服務(wù)端。
// Establish a connection. 0.000 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 0.000 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 0.000 bind(3, ..., ...) = 0 0.000 listen(3, 1) = 0 0.000...0.200 accept(3, ..., ...) = 4 0.100 < S 0:0(0) win 32792 <mss 1000,nop,wscale 7> 0.100 > S. 0:0(0) ack 1 <mss 1460,nop,wscale 6> 0.200 < . 1:1(0) ack 1 win 257 //服務(wù)器端調(diào)用系統(tǒng)調(diào)用,預(yù)期發(fā)出2段數(shù)據(jù)包。 0.300 write(4, ..., 2000) = 2000 //0.300 > P. 1:2001(2000) ack 1 0.300 > . 1:1001(1000) ack 1 0.300 > P. 1001:2001(1000) ack 1
1.客戶端場景構(gòu)造
構(gòu)造服務(wù)器端場景:數(shù)據(jù)包輸入端是服務(wù)端。數(shù)據(jù)包輸出端是系統(tǒng)調(diào)用,充當(dāng)客戶端。
// Create a socket and set it to non-blocking. 0.000 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 0.000 fcntl(3, F_GETFL) = 0x2 (flags O_RDWR) 0.000 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0 // Establish connection and verify that there was no error. 0.100 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress) 0.100 > S 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop,wscale 6> 0.200 < S. 0:0(0) ack 1 win 5792 <mss 1460,sackOK,TS val 700 ecr 100,nop,wscale 7> 0.200 > . 1:1(0) ack 1 <nop,nop,TS val 200 ecr 700> //客戶端調(diào)用系統(tǒng)調(diào)用,預(yù)期發(fā)出http請求。 // Send the HTTP request. 0.200 write(3, ..., 57) = 57 0.200 > P. 1:58(57) ack 1 <nop,nop,TS val 200 ecr 700> 0.300 < . 1:1(0) ack 58 win 92 <nop,nop,TS val 800 ecr 200>
以上是“l(fā)inux中Packetdrill如何使用”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
當(dāng)前名稱:linux中Packetdrill如何使用
文章起源:http://m.rwnh.cn/article0/jepioo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、關(guān)鍵詞優(yōu)化、品牌網(wǎng)站制作、Google、虛擬主機、手機網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)