이더넷 최대 전송 단위(MTU)와 TCP 최대 세그먼트 크기(MSS)를 혼동하는 분들이 계신 것 같아, 아래 내용을 통해 이를 명확히 설명해 드리고자 합니다. 그래도 여전히(혹은 이제서야) 혼란스럽다면, 주저하지 말고 댓글을 남기거나 이메일을 보내어 자세한 설명을 요청해 주시기 바랍니다.
먼저, STCP는 로컬 서브넷에 있는 호스트로 전송되는 TCP 세그먼트와 원격 서브넷(즉, 라우터를 경유하여)에 있는 호스트로 전송되는 세그먼트를 구분합니다. 로컬 서브넷에 있는 호스트로 전송되는 세그먼트의 MSS는 이더넷 MTU와 관련이 있습니다. 구체적으로 MSS는 MTU에서 IP 헤더 크기와 TCP 헤더 크기를 뺀 값입니다. 17.1 이전 릴리스(17.1에 대해서는 잠시 후에 자세히 설명하겠습니다)에서는 이로 인해 MSS가 1500 – 20 – 20, 즉 1460이 됩니다. 원격 서브넷의 호스트로 전송되는 세그먼트는 536의 MSS를 사용합니다. STCP는 RFC 791 및 RFC 879의 요구 사항에 따라 원격 세그먼트에 더 작은 MSS를 사용합니다. 저는 2004년 6월 Stratus 고객 e뉴스레터에 실린 기사에서 MSS를 조정(증가)하는 방법과 잠재적인 문제점에 대해 다룬 바 있습니다. 해당 기사의 사본은 여기에서 확인하실 수 있습니다. 이 기사는 VOS 14.7 릴리스의 예시를 바탕으로 작성되었으나, 내용은 여전히 유효합니다(OpenVOS 17.1 릴리스 기준).
OpenVOS 17.1 버전에서는 점보 이더넷 프레임에 대한 지원이 추가되었습니다. 점보 프레임을 사용하면 이더넷 프레임에 1500바이트 이상의 데이터를 담을 수 있으며, 이는 이더넷 MTU가 증가함을 의미합니다. 기본 MTU는 여전히 1500이지만, 인터페이스를 구성할 때 “–mtu” 인수를 사용하여 이 값을 늘릴 수 있습니다(예 1). MTU 인수의 최대값은 하드웨어에 따라 16110입니다(표 1 참조).
ifconfig #sdlmux.m16.11-2 172.16.1.116 -netmask 255.255.255.0 -mtu 9200 -add
Adding interface %phx_vos#sdlmux.m16.11-2 with IP address 172.16.1.116
%phx_vos#sdlmux.m16.11-2: <UP, BROADCAST, RUNNING, NOFORWARDBROADCAST, KEEPALIVE
+, MTU:9200>
172.16.1.116 netmask 0xffffff00 broadcast 172.16.1.255
|
| 예 1 – 인터페이스 구성 시 MTU 설정 |
| 어댑터 유형 | MTU |
| V100, V200, V400에 내장된 어댑터 | 1500 |
| V150, V250, V300, V500에 내장된 어댑터 V2302, V2404, V4304, V4408, V6308, V6408에 내장된 어댑터 |
9200 |
| U571V 단일 포트 10/100/1000 Mbps 동축 어댑터 | 1500 |
| U574V-LC 듀얼 포트 1000 Mbps 광 어댑터 U575V 듀얼 포트 10/100/1000 Mbps 동축 어댑터 U578V 4포트 10/100/1000 Mbps 동축 어댑터 U582V 4포트 10/100/1000 Mbps 동축 어댑터 U583V 4포트 1000 Mbps 광 어댑터 |
9200 |
| U584V 듀얼 포트 10,000 Mbps 광 어댑터 | 16110 |
| U776V 4포트 1000Mbps 광 어댑터 | 9200 |
| 표 1 – 하드웨어 유형별 MTU 값 |
MTU 값을 더 크게 설정한 후에는 STCP가 로컬 연결에 대해 더 큰 MSS를 알리는 것을 확인할 수 있습니다. 0x23c8은 10진수로 9160입니다.
9:04:55.912 Xmit Ether Dst 00:16:97:c4:01:aa Src 00:00:a8:41:52:22 Type 0800
+(IP)
IP Ver/HL 45, ToS 0, Len 3c, ID 0, Flg/Frg 0, TTL 3c, Prtl 6
Cksum 23fc, Src ac100174, Dst ac10012c
TCP from 172.16.1.116.59410 to 172.16.1.44.9182
seq 3764213089, ack n.a., window 8192, 20 data bytes, flags Syn.
X/Off 0a, Flags 02, Cksum d329, Urg-> 0000
offset 0 . . . 4 . . . 8 . . . C . . . 0...4... 8...C...
0 2 4 23 c8 3 3 6 4 2 8 a 18 bf 3f d6 0 <<#H<<<< <<<<??V
10 0 0 0 0
|
하지만 원격 연결의 경우 여전히 더 작은 MSS를 사용하며, 0x218은 10진수로 536입니다.
9:20:34.051 Xmit Ether Dst 00:16:97:c4:01:aa Src 00:00:a8:41:52:22 Type 0800
+(IP)
IP Ver/HL 45, ToS 0, Len 3c, ID 0, Flg/Frg 0, TTL 3c, Prtl 6
Cksum 1086, Src ac100174, Dst c0a8000a
TCP from 172.16.1.116.49186 to 192.168.0.10.9182
seq 1916893234, ack n.a., window 8192, 20 data bytes, flags Syn.
X/Off 0a, Flags 02, Cksum de8e, Urg-> 0000
offset 0 . . . 4 . . . 8 . . . C . . . 0...4... 8...C...
0 2 4 2 18 3 3 6 4 2 8 a 0 1 69 a 0 <<<<<<<< <<< <i<
10 0 0 0 0
|
원격 연결의 최소 MSS는 1460(TCP 헤더 포함 시 1480)을 초과하여 늘릴 수 없습니다.
as: set_stcp_param min_mss 9160;
set_stcp_param: 인수가 허용된 범위 내에 있지 않습니다. 오류:
'param_value'. [500-1480] 허용됨;
as:
|
연결의 양쪽 모두 더 큰 MSS를 알리지 않는 한 실질적인 효과는 없습니다. 예를 들어, FTP 서버가 MTU 9200으로 설정되어 있고 MSS 9160을 알리고 있더라도, 클라이언트가 MSS 1460(0x5b4)을 알리고 있기 때문에 서버가 한 세그먼트에 전송할 수 있는 최대 바이트 수는 1460바이트가 됩니다.
11:02:49.758 Xmit Ether Dst 00:00:a8:42:3b:6e Src 00:00:a8:41:52:22 Type 0800
+(IP)
IP Ver/HL 45, ToS 0, Len 3c, ID 5, Flg/Frg 0, TTL 3c, Prtl 6
Cksum 2401, Src ac100174, Dst ac100122
TCP from 172.16.1.116.ftp-data to 172.16.1.34.49343
seq 2092638702, ack n.a., window 8192, 20 data bytes, flags Syn.
X/Off 0a, Flags 02, Cksum 7c62, Urg-> 0000
offset 0 . . . 4 . . . 8 . . . C . . . 0...4... 8...C...
0 2 4 23 c8 3 3 6 4 2 8 a 0 19 5c b5 0 <<#H<<<< <<< <5
10 0 0 0 0
11:02:49.758 Rcvd Ether Dst 00:00:a8:41:52:22 Src 00:00:a8:42:3b:6e Type 0800
+(IP)
IP Ver/HL 45, ToS 0, Len 3c, ID 1bcb, Flg/Frg 0, TTL 3c, Prtl 6
Cksum 083b, Src ac100122, Dst ac100174
TCP from 172.16.1.34.49343 to 172.16.1.116.ftp-data
seq 3565222463, ack 2092638703, window 8192, 20 data bytes, flags Syn Ack.
X/Off 0a, Flags 12, Cksum fef7, Urg-> 0000
offset 0 . . . 4 . . . 8 . . . C . . . 0...4... 8...C...
0 2 4 5 b4 3 3 6 4 2 8 a 13 cc 99 0 0 <<<4<<<< <<<<L>
10 19 5c b5 0 <5
. . . .
11:02:50.620 Xmit Ether Dst 00:00:a8:42:3b:6e Src 00:00:a8:41:52:22 Type 0800
+(IP)
IP Ver/HL 45, ToS 0, Len 5dc, ID 8, Flg/Frg 0, TTL 3c, Prtl 6
Cksum 1e5e, Src ac100174, Dst ac100122
TCP from 172.16.1.116.ftp-data to 172.16.1.34.49343
seq 2092638703, ack 3565222464, window 128, 1460 data bytes, flags Push A
+ck.
X/Off 08, Flags 18, Cksum 7467, Urg-> 0000
offset 0 . . . 4 . . . 8 . . . C . . . 0...4... 8...C...
. . . .
|
양측이 모두 더 큰 MSS를 알리고 있더라도, 각 프레임에 최대 용량의 데이터가 담길 것이라는 보장은 없습니다. 예를 들어, 클라이언트와 서버 모두 MSS를 9160으로 알리고 있지만, 해당 애플리케이션이 전송하도록 설계된 최대 용량이 8204바이트에 불과하기 때문에 세그먼트 크기는 8204바이트에 그칩니다.
11:33:40.492 Xmit Ether Dst 00:00:a8:43:ba:64 Src 00:00:a8:41:52:22 Type 0800
+(IP)
IP Ver/HL 45, ToS 0, Len 3c, ID 34, Flg/Frg 0, TTL 3c, Prtl 6
Cksum 231b, Src ac100174, Dst ac1001d9
TCP from 172.16.1.116.ftp-data to 172.16.1.217.49430
seq 851197707, ack n.a., window 8192, 20 data bytes, flags Syn.
X/Off 0a, Flags 02, Cksum d8f7, Urg-> 0000
offset 0 . . . 4 . . . 8 . . . C . . . 0...4... 8...C...
0 2 4 23 c8 3 3 6 4 2 8 a 0 20 9b 7d 0 <<#H<<<< <<< >}
10 0 0 0 0
11:33:40.493 Rcvd Ether Dst 00:00:a8:41:52:22 Src 00:00:a8:43:ba:64 Type 0800
+(IP)
IP Ver/HL 45, ToS 0, Len 3c, ID 33, Flg/Frg 0, TTL 3c, Prtl 6
Cksum 231c, Src ac1001d9, Dst ac100174
TCP from 172.16.1.217.49430 to 172.16.1.116.ftp-data
seq 3989207776, ack 851197708, window 8192, 20 data bytes, flags Syn Ack.
X/Off 0a, Flags 12, Cksum d75d, Urg-> 0000
offset 0 . . . 4 . . . 8 . . . C . . . 0...4... 8...C...
0 2 4 23 c8 3 3 6 4 2 8 a 0 e e1 8a 0 <<#H<<<< <<< <a>
10 20 9b 7d 0 >}
. . . .
11:33:40.504 Xmit Ether Dst 00:00:a8:43:ba:64 Src 00:00:a8:41:52:22 Type 0800
+(IP)
IP Ver/HL 45, ToS 0, Len 2034, ID 37, Flg/Frg 0, TTL 3c, Prtl 6
Cksum 0320, Src ac100174, Dst ac1001d9
TCP from 172.16.1.116.ftp-data to 172.16.1.217.49430
seq 851197708, ack 3989207777, window 128, 8204 data bytes, flags Ack.
X/Off 08, Flags 10, Cksum ee81, Urg-> 0000
offset 0 . . . 4 . . . 8 . . . C . . . 0...4... 8...C...
. . . .
|
Finally just setting a large MTU on your hosts is not enough; you also have to make sure that all network devices between the two hosts are configured to allow the larger frame size. If not then what you will find is that everything will work correctly when the host uses small (<= 1460) segments, but if it transmits a larger segment, that segment will be dropped by the network device and the connection will eventually fail with a timeout condition of some kind. Larger segments may be sent because the application sends it or because STCP combines smaller segments. This can make for random and very frustrating failures.
