最初に少し背景を説明しますが、TCPには最大セグメントサイズ(MSS)と呼ばれる概念があります。これは、TCP スタックが受け入れる最大のセグメント (データの) です。これは、接続が確立されたときに、SYN セグメントのリモート・ピアにアドバタイズされます。以下のパケットデコードは、TCP MSS オプションがハイライトされた SYN セグメントを示しています。すべての TCP オプションは同じフォーマットで、オプション番号に 1 バイト、この場合は 2 バイト、オプションの合計長 (4) に 1 バイト、オプションの値 (この場合は 5b4 16 進数または 1460 進数) に 1 バイトです。
packet_monitor -interface #sdlmux.m16.11-3 -hex_dump -numeric -time_stamp -verbo +se -pkt_hdr -filter -host 10.64.77.50 dir icmp type + tcp hh:mm:ss.ttt dir len proto source destination src port ds +t port type 10:11:56.751 Xmit Ether Dst 00:23:54:52:18:6e Src 00:00:a8:43:52:22 Type 0800 +(IP) IP Ver/HL 45, ToS 0, Len 2c, ID be0b, Flg/Frg 0, TTL 3c, Prtl 6 Cksum dcdd, Src a404d80, Dst a404d32 TCP from 10.64.77.128.55911 to 10.64.77.50.telnet seq 1305537174, ack n.a., window 8192, 4 data bytes, flags Syn. X/Off 06, Flags 02, Cksum 815d, Urg-> 0000 offset 0 . . . 4 . . . 8 . . . C . . . 0...4...8...C... 0 2 4 5 b4 <<<4
ローカルネットワーク上のホストへの接続では、STCPは1460の値を使用します。すべてのプロトコルオーバーヘッドを加えると、イーサネットフレームの最大サイズである1518バイトのイーサネットフレームになります。非ローカルセグメント上のホストへの接続では、STCPはmin_mssパラメータから派生した値を使用します。デフォルトのmin_mss値を使用すると、MSS値は536になります。この値は、すべてのIPベースのネットワーク機器、すなわちルータがIPフラグメンテーションなしで転送することを希望しなければならない最小サイズであり、536を最小値として確立した仕様は1983年のRFC 879 - "The TCP Maximum Segment Size and related Topics"に書かれています。
今日では、すべてのルータがより大きなサイズを扱えるようになっている可能性が高いです。そのため、STCPの最小値を536からもっと大きなものに上げることができます。どのくらい大きくするかが重要な問題です。それを大きくしすぎると危険なのは断片化です。最悪のシナリオですが、診断するのが最も簡単なのは、ルータが断片化するのではなく、TCPセグメントを破棄することを選択するということです。この場合、接続を確立することはできますが、データを転送するときに接続に失敗します。送信ホストのトレースは、接続がタイムアウトするまで大きなTCPセグメントの複数回の再送を示します。トレースはまた、セグメントを破棄しているルータからの ICMP 宛先到達不能メッセージを示すこともあります。ルータがセグメントをフラグメント化することを選択した場合、おそらくフラグメント化処理の優先度は低くなるでしょう。また、破損や輻輳のためにセグメントを失う確率は、フラグメントの数に応じて高くなります。これがそうであるかどうかを知る最も簡単な方法は、モジュール上で packet_monitor トレースを実行することです。TCP セグメントがフラグメントとして入ってきたら、フラグメントが発生していることがわかります。
以下の 3 つのイーサネットフレームは、3 つの部分に断片化された 1 つの TCP セグメントを表しています。Flg/Flg の値が 2000 であることから、最初のフレームがフラグメントであることがわかります。2はMore Fragmentsビットが設定されていることを示し、000はフラグメントオフセットで、この場合0は最初のフラグメントであることを示しています。パケットモニタは、実際には次の2フレームをフラグメントとしてフラグを立てます。フレーム2のFlg/Flgの値は2048で、2はMore Fragmentsビットがセットされていることを示し、48は元のIPデータグラムのデータのオフセット(8バイトの倍数)です。3番目のフレームは、Flg/Fragがちょうど90、より正確には0090である。More Fragments ビットが 0 であるため、これが最後のフラグメントであることがわかります。これらのフレームはすべて同じIP ID値2e87を持っているので、これらのフレームはすべて一緒に属していることがわかります。最初のフレームのデータ長は、設定されるべきMSS値を示しています。
15:52:27.081 Rcvd Ether Dst 00:00:a8:43:52:22 Src 00:12:3f:82:57:10 Type 0800 +(IP) IP Ver/HL 45, ToS 8, Len 254, ID 2e87, Flg/Frg 2000, TTL 3f, Prtl 6 Cksum 1422, Src c0a86432, Dst a404d80 TCP from 192.168.100.50.32781 to 10.64.77.128.ftp-data seq 568258166, ack 840605671, window 5440, 556 data bytes, flags Ack. X/Off 05, Flags 10, Cksum d149, Urg-> 0000 offset 0 . . . 4 . . . 8 . . . C . . . 0…4… 8…C… 0 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 * 5678901234567890 10 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 * 1234567890123456 20 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 * 7890123456789012 30 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 * 3456789012345678 40 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 * 9012345678901234 50 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 * 5678901234567890 60 d a 31 32 33 34 35 36 37 38 39 30 31 32 33 34 * <<12345678901234 70 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 * 5678901234567890
15:52:33.793 Rcvd Ether Dst 00:00:a8:43:52:22 Src 00:12:3f:82:57:10 Type 0800 +(IP) IP Ver/HL 45, ToS 8, Len 254, ID 2e87, Flg/Frg 2048, TTL 3f, Prtl 6 Cksum 13da, Src c0a86432, Dst a404d80 TCP from 192.168.100.50. to 10.64.77.128. *fragments*, 576 bytes data offset 0 . . . 4 . . . 8 . . . C . . . 0…4… 8…C… 0 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 * 1234567890123456 10 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 * 7890123456789012 20 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 * 3456789012345678 30 39 30 d a 31 32 33 34 35 36 37 38 39 30 31 32 * 90<<123456789012 40 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 * 3456789012345678 50 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 * 9012345678901234 60 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 * 5678901234567890 70 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 * 1234567890123456
15:52:33.793 Rcvd Ether Dst 00:00:a8:43:52:22 Src 00:12:3f:82:57:10 Type 0800 +(IP) IP Ver/HL 45, ToS 8, Len f8, ID 2e87, Flg/Frg 90, TTL 3f, Prtl 6 Cksum 34ee, Src c0a86432, Dst a404d80 TCP from 192.168.100.50. to 10.64.77.128. *fragments., 228 bytes data offset 0 . . . 4 . . . 8 . . . C . . . 0…4… 8…C… 0 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 * 5678901234567890 10 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 * 1234567890123456 20 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 * 7890123456789012 30 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 * 3456789012345678 40 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 * 9012345678901234 50 35 36 37 38 39 30 d a 31 32 33 34 35 36 37 38 * 567890<<12345678 60 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 * 9012345678901234 70 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 * 5678901234567890
MSS 値を増加させることの問題は、すべての TCP 接続に対して増加させることです。1 つまたはいくつかのデスティネーションに対してだけ増加させることはできません。したがって、この変更がすべての接続に与える影響を測定するために、慎重にテストする必要があります。
現在のMSSの値を確認し、以下の2つのコマンドで変更することができます。
analyze_system -request_line 'list_stcp_params min_mss' -quit
OpenVOS Release 17.0.1as, analyze_system Release 17.0.1as
Current process is 357, ptep 8FA86000, Noah_Davids.SysAdmin
maximum tcp segment size [500-1480] (min_mss) 556
ready 10:52:07
analyze_system -request_line 'set_stcp_param min_mss 1480' -quit
OpenVOS Release 17.0.1as, analyze_system Release 17.0.1as
Current process is 357, ptep 8FA86000, Noah_Davids.SysAdmin
Changing maximum tcp segment size (min_mss)
from 556 to 1480
ready 10:52:24
パラメータ名の min_mss は MSS 値を意味していますが、実際には MSS 値に TCP ヘッダの長さ 20 バイトを加えたものです。上記の例では、min_mss の値を 556+20 または 576 に設定します。
では、MSSの値を上げることでどの程度のブーストが得られるのでしょうか?オーバーヘッドバイトを追加するVPN接続の普及のために、私は1480(1460の実際のTCP MSS)の最大値を設定することをお勧めしません。私は、1220(実際のMSS 1200)バイトを言う、もう少し小さいものをお勧めします。536バイトのセグメントを使用して10メガバイトのデータを送信すると仮定すると、18657フレームを必要とし、オーバーヘッド(8バイトのイーサネットプリアンブル+14バイトのイーサネットヘッダ+20バイトのIPヘッダ+20バイトのTCPヘッダ+4バイトのイーサネットトレーラ+イーサネットのフレーム間ギャップのための有効な12バイト)を含む総バイト数は11,455,246バイトになります。1200バイトのセグメントを使用している場合は、8334フレーム、合計バイト数10,650,052、または9%強小さくなります。しかし、MSSの値は受け入れられる最大のセグメントのアドバタイズメントであり、送信側のホストがそのような大きなセグメントを実際に送信する必要はありません。しかし、送信すると仮定して、他のボトルネックがないと仮定すると、9%のスループットのブートを得たことになります。
UDP側で何かできるのかな?
UDPには最大セグメントサイズという概念がないので、それを調整するためのパラメータがありません。