1. Packetdrillのコンパイルとインストール
/* オフロードフラグを一般的なイーサネットデバイスと同じように設定します */ 静的 void set_device_offload_flags(構造体 local_netdev *netdev) { #ifdef Linux の場合 // const u32 オフロード = // 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"); #終了 } ./configure && メイク 使い方 ./パケットドリルテスト.pkt test.pkt は、Packetdrill 構文で記述されたテスト スクリプトです。 成功: 出力なし。スクリプトが正しく、すべてが期待どおりであることを示します。 失敗: スクリプトが失敗した場所とその理由を示します。 2. Packetdrillは独自のテストケースを実行する
// 4 つのパケットが未処理で、受信側が SACK を送信している状態で高速再送信をテストします。 // このバリアントでは、受信側は SACK をサポートします。 // 接続を確立します。 0 ソケット(..., SOCK_STREAM, IPPROTO_TCP) = 3 +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 +0 バインド(3, ..., ...) = 0 +0 聞く(3, 1) = 0 //3ウェイハンドシェイク+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 勝利 257 +0 受け入れる(3, ..., ...) = 4 // システム コール、プロトコル スタックに 100 バイトを送信させます // 1 つのデータ セグメントを送信して ACK を取得します。そのため、cwnd は 4 になります。 +0 書き込み(4, ..., 1000) = 1000 //プロトコルスタックはpsh、ackを送信すると予想されますが、実際にはack1を送信します //+0 > P. 1:1001(1000) 確認 2 //プロトコルスタックにackを挿入する +.1 < . 1:1(0) ack 1001 勝利 257 // 4 つのデータ セグメントを書き込みます。 //システムコール、プロトコルスタックに4000バイト+0を送信させる write(4, ..., 4000) = 4000 //プロトコル スタックは psh、ack を送信すると予想されますが、実際には 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) 確認1 // 3 つの SACK を取得します。 // プロトコルスタックに 3 つの 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> // 重複した ACK を 3 つ受信したので、高速再送信を行います。 //プロトコルスタックは高速再送信シーケンス 1001:2001、ack 1 を発行することが期待されます //+0 > . 1001:2001(1000) 確認 1 // 受信側はすべてのデータを ACK します。 //プロトコル スタックに ACK を送信し、すべてのメッセージの ACK に応答します。 +.1 < . 1:1(0) ack 6001 勝利 257 4. fr-4pkt-sack-linux.pkt を次のように変更します。 +0 > P. 1:1001(1000) 確認応答 2 +0 > P. 1:1001(1000) 確認応答 1 //+0 > P. 1001:5001(4000) 確認応答 1 +0 > . 1001:2001(1000) 確認 1 +0 > . 2001:3001(1000) ack 1 +0 > . 3001:4001(1000) 確認 1 +0 > P.4001:5001(1000) 確認1 [注: packetdrill が提供するテスト ケースを実行する際にエラーが発生する場合、通常はプロトコル スタックが送信したパケットが期待されるパケットと一致していないことが原因です。まず、期待されるパケットよりも大きい部分を排除してからテスト ケースを実行し、パケットをキャプチャして期待される結果を分析してください。通常、3ウェイハンドシェイクmssの制限によるものです。
// 3 回の繰り返し ack 1001 を実装するためにパケットを自分で構築します。 07:57:36.469280 IP 192.0.2.1.36840 > TENCENT64.site.webcache: フラグ [.]、ack 1001、win 257、オプション [sack 1 {2001:3001}、nop、nop]、長さ 0 07:57:36.469836 IP 192.0.2.1.36840 > TENCENT64.site.webcache: フラグ [.]、ack 1001、win 257、オプション [sack 1 {2001:4001}、nop、nop]、長さ 0 07:57:36.470349 IP 192.0.2.1.36840 > TENCENT64.site.webcache: フラグ [.]、ack 1001、win 257、オプション [sack 1 {2001:5001}、nop、nop]、長さ 0 // プロトコル スタックは高速再送信を開始します。シーケンス 1001:2001、ack 1,1000 07:57:36.470376 IP TENCENT64.site.webcache > 192.0.2.1.36840: フラグ [.]、シーケンス 1001:2001、ack 1、win 229、長さ 1000 3. Packetdrillは独自のテストケースの説明を説明しています ここでは主にpacketdrillの基本的な構文について説明します。 スクリプトには、データ パケット、システム コール、シェル コマンド、Python ステートメントの 4 種類のステートメントを含めることができます。
データパケットは入力データパケットと出力データパケットに分かれており、フォーマットはtcpdumpに似ています。 入力データ パケット (< は入力を意味します): Packetdrill は実際のデータ パケットを構築し、それをプロトコル スタックに挿入します。 例: 0.100 < S 0:0(0) 勝利 32792 <mss 1000、nop、nop、sackOK、nop、wscale 7> 0.250 < [1:1461(1460)] icmp 到達不能 frag_needed mtu 1200 出力データ パケット (> は出力を示します): packetdrill は、プロトコル スタックが実際にそのようなパケットを送信するかどうかを確認します。 +0 > udp (1472)
システムコールの形式は strace に似ています。 一般的なシステムコールの例: connect(3, ..., ...) = -1 EINPROGRESS (操作が進行中) //クライアントがサーバーに接続 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0 //socketoptを取得 fcntl(3, F_SETFL, O_RDWR) = 0 //Fcntl 設定 ioctl(4, SIOCINQ, [1000]) = 0 //Ioctl 設定 read(3, ..., 1024) = 785 //データ読み取り write(3, ..., 57) = 57 //データ書き込み close(3) = 0 //接続を閉じる socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 //Tcp ソケット setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 //アドレス再利用を設定 bind(3, ..., ...) = 0 //ポートをバインド listen(3, 1) = 0 //ポートをリッスン accept(3, ..., ...) = 4 //接続を受け入れる
一般的な使用法としては、シェル スクリプトを使用してカーネル パラメータを設定したり、シェル コマンドを呼び出して TCP 統計を収集したりすることが挙げられます。設定 例: +0 `sysctl -q net.ipv4.tcp_timestamps=0` +0 `ss -4 -n 状態 SYN-RECV | grep 192.168.0.1:8080 > /dev/null`
一般的な使用法は、Python の assert を使用して、tcp_info の情報が期待どおりであるかどうかをアサートすることです。 例: 0.310% tcpi_reordering == 3 をアサートする tcpi_unacked == 10 をアサートする tcpi_sacked == 6 をアサートする tcpi_ca_state == TCP_CA_Recovery をアサートする }%
各ステートメントは、実行された時刻、またはイベントの発生が予想される時刻を示すタイムスタンプで始まる必要があります。タイミングの問題によりテストケースが失敗する可能性があります。 タイムスタンプにはさまざまな形式を使用できます。 絶対値: 0.75 相対: +0.2 ワイルドカード(いつでも):* 範囲(絶対時間間隔):0.750〜0.900 相対範囲: +0.1~+0.2 緩い(許容誤差値): --tolerance_usecs=800 ブロッキング(ブロッキング時間間隔):0.750...0.900 対応するイベントが指定されたタイムスタンプで発生しない場合は、エラーが報告され、イベントの実際の発生時刻が通知されます。 +1.0 > S. 0:0(0) ack 1 <mss 1460,nop,nop,sackOK,nop,wscale 6> TCP は 1 秒後に SYNACK パケットを送信することが予想されます。 実際の使用では、一般的に –tolerance_usecs=405000 が指定され、これは 4 ミリ秒の時間誤差が許容されることを意味します。 4. Packetdrillが基本シナリオ構築テストを実装 シーンのシーン構造は、クライアント シーンまたはサーバー シーンのいずれかです。特定のパッケージを構築する方法の詳細については、packetdrill に付属するテスト ケースを参照してください。 1. サーバーシナリオ サーバー側のシナリオを構築します。データ パケットの入力側はクライアントです。パケットの出力先はサーバーとして機能するシステムコールです。 // 接続を確立します。 0.000 ソケット(..., SOCK_STREAM, IPPROTO_TCP) = 3 0.000 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 0.000 バインド(3, ..., ...) = 0 0.000 聞く(3, 1) = 0 0.000...0.200 accept(3, ..., ...) = 4 0.100 < S 0:0(0) 勝利 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 勝利 257 // サーバーはシステム コールを呼び出し、2 つのパケットを送信することを期待します。 0.300 書き込み(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. クライアントシーンの構築 サーバー側のシナリオを構築します。データ パケットの入力側はサーバー側です。パケット出力側はクライアントとして機能するシステムコールです。 // ソケットを作成し、非ブロッキングに設定します。 0.000 ソケット(..., SOCK_STREAM, IPPROTO_TCP) = 3 0.000 fcntl(3, F_GETFL) = 0x2 (フラグ O_RDWR) 0.000 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0 // 接続を確立し、エラーがなかったことを確認します。 0.100 connect(3, ..., ...) = -1 EINPROGRESS (操作が進行中です) 0.100 > S 0:0(0) <mss 1460、sackOK、TS値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 値 200 ecr 700> // クライアントは、http リクエストを行うことを期待してシステム コールを呼び出します。 // HTTP リクエストを送信します。 0.200 書き込み(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> 要約する 以上がこの記事の全内容です。この記事の内容が皆様の勉強や仕事に何らかの参考学習価値をもたらすことを願います。123WORDPRESS.COM をご愛顧いただき、誠にありがとうございます。これについてもっと知りたい場合は、次のリンクをご覧ください。 以下もご興味があるかもしれません:
|
<<: CentOS7 64ビットインストールmysqlグラフィックチュートリアル
一般的に、マウスは上向きの斜め矢印として表示され、テキストの上に移動すると垂直線になり、ハイパーリン...
前回の投稿では、Web ページの作成方法について説明しました。Web サイトは多くの Web ページ...
vue+remを使用したカスタムカルーセルチャートの実装は参考までに。具体的な内容は以下のとおりです...
序文この記事はかなり詳細で、少し面倒です。他のチュートリアル ドキュメントでは多くの手順が省略されて...
結果:実装コードhtml <ul class="スライド"> <...
Zabbix独自のWEBインターフェースを例に、Web監視の設定を行います。環境: zabbix4....
目次基本的な紹介入門テスト (Excel ファイルからのデータの読み取り)ステップ1: Maven座...
クラスターを構成する際に問題が発生しました。当初は 3 台の仮想マシンすべてが外部ネットワークに p...
なぜ詰まっているのでしょうか?言及しなければならない前提があります。フロントエンド開発者は皆、ブラウ...
目次DOMノード要素ノード:テキストノード:プロパティ ノード:要素を取得getElementByI...
この記事では、例を使用して、MySQL トリガーの概念、原則、および使用方法を説明します。ご参考まで...
このプロジェクトでは MySQL を使用する必要があります。これまで Windows では常に確実に...
1. ドキュメントフローとフローティング1. ドキュメントフローとは何ですか? HTML では、ドキ...
Linux chmodコマンドを使用して、ターゲット ファイルにアクセス、読み取り、書き込み、または...
ボリュームとは何ですか?ボリュームは英語で容量を意味し、Docker ではデータ ボリューム、つまり...