DNS แก้ได้แล้ว เซสชัน SSH ยังอยู่ แต่พออัปโหลดไฟล์ใหญ่กลับค้าง ขณะที่ ping ไปยังโฮสต์เดิมยังตอบสนอง การแยกกันแบบนี้ชี้ไปที่ขนาดแพ็กเก็ต ไม่ใช่ทันเนลที่เสีย ทันเนลซ้อนกันไปถึงจุดนั้นที่ขนาดที่ไม่มีทันเนลใดอันเดียวจะไปถึง ทันเนลชั้นในยังปกติดี มันเพียงได้รับแพ็กเก็ตที่ไม่พอดีอีกต่อไป

MTU ของเส้นทางหายไปไหนจริง ๆ

การห่อหุ้มแต่ละชั้นใช้ไบต์ก่อนที่ชั้นถัดไปจะได้คิว เส้นทาง Ethernet ให้ 1500 ไบต์แก่แพ็กเก็ตชั้นนอก และทันเนลชั้นนอกก็ใช้ส่วนของตนก่อนที่อะไรข้างในจะถูกกำหนดที่อยู่ได้ ค่าโอเวอร์เฮดที่เดาไว้หนึ่งค่าจะผิดไปเท่ากับจำนวนที่สำคัญพอดี

เรียงชั้นตามลำดับ: เส้นทางเข้าถึง การขนส่งชั้นนอก ทันเนลชั้นนอก การขนส่งชั้นใน ทันเนลชั้นใน แอปพลิเคชัน นับเฮดเดอร์แต่ละอันหนึ่งครั้ง และแยก UDP ออกจากเฮดเดอร์กับแท็กของทันเนลเอง

สองชั้น WireGuard นับครั้งเดียว

ยกเส้นทางเข้าถึง IPv4 ที่มีทันเนล WireGuard หนึ่งอันซ้อนอยู่ในอีกอัน ชั้นนอกใช้ 20 ไบต์ IPv4, 8 ไบต์ UDP และ 32 ไบต์สำหรับเฮดเดอร์ข้อมูล WireGuard พร้อมแท็กยืนยันตัวตน ข้างในนั้นทันเนลชั้นในต้องการเฮดเดอร์ IPv4 20 ไบต์และเฮดเดอร์ UDP 8 ไบต์ของตัวเองก่อนโอเวอร์เฮด WireGuard 32 ไบต์ชุดที่สอง ส่วนที่เหลือบรรจุเฮดเดอร์ IPv4 เฮดเดอร์ TCP และข้อมูล เส้นทางชั้นนอกแบบ IPv6 ใช้ 40 แทน 20 และเหลือ 1320

LayerBytes
Path MTU1500
Outer IPv4 header20
Outer UDP header8
Outer WireGuard header and tag32
Inner transport IPv4 header20
Inner UDP header8
Inner WireGuard header and tag32
Innermost IPv4 header20
TCP header20
Payload that fits1340

ผลคำนวณลงเอยที่ 1340 ไบต์ หนึ่งชั้นภายใต้กฎเดียวกันเหลือ 1400 สำหรับเพย์โหลด TCP นั่นคือ 1500 ลบ 20, 8, 32, 20 และ 20 และส่วนต่าง 60 ไบต์ก็คือการห่อหุ้มชั้นในที่ทันเนลที่สองเพิ่มเข้ามาพอดี

นำ 1400 ไปใช้กับเส้นทางซ้อนกัน แล้วทันเนลชั้นในจะขาดไป 60 ไบต์ มองไม่เห็นจนกว่าแพ็กเก็ตจะใหญ่พอที่ต้องการมัน การเติมเต็มและตัวเลือกการแบ่งส่วนของโปรโตคอลเองก็ขยับตัวเลขอีกครั้ง ดังนั้นจงเชื่อตาราง

MTU, MSS และการแบ่งส่วนทำงานคนละที่

MTU ของอินเทอร์เฟซจำกัดสิ่งที่อินเทอร์เฟซจะส่งออก ส่วนการบีบ MSS ใน TCP เปลี่ยนสิ่งที่คู่ TCP ยินดีจะส่ง การบีบช่วยแก้เซสชัน TCP และไม่ทำอะไรให้ดาตาแกรม UDP ขนาดใหญ่ นี่คือวิธีที่การแก้ปัญหาดูสำเร็จกับแอปหนึ่งและพลาดอีกแอปอย่างเงียบ ๆ ตัวเลือกการแบ่งส่วนของโปรโตคอลเองคือคันโยกที่สามพร้อมความล้มเหลวของมันเอง MTU ของอินเทอร์เฟซคือก้าวแรกที่พบได้บ่อยและหยาบที่สุด

ทันเนลแบบบริดจ์และแบบเราเตอร์บรรทุกเฟรมต่างกัน ตัวเลขจากการติดตั้งอื่นจึงแทบไม่ถ่ายโอน การค้นหา MTU ของเส้นทาง ซึ่งอธิบายไว้ใน RFC 8201ช่วยได้เพียงตราบเท่าที่ข้อความ ICMP ที่มันพึ่งพาอยู่ถูกปล่อยให้ผ่าน

หาชั้นที่ขาดไป

ตรวจสอบแต่ละทันเนลแยกกันก่อนจะซ้อนกัน หากข้อกำหนดอนุญาตให้เปรียบเทียบ โพรบขนาดคงที่ตัดสินเรื่องนี้: ping -M do -s 1472 -c 3 10.8.0.1 ส่งแพ็กเก็ต IPv4 ขนาด 1500 ไบต์เต็ม ๆ ภายในชั้นนั้น เพิ่มชั้นที่สองแล้วทำโพรบเดิมซ้ำ เพื่อให้ความล้มเหลวใด ๆ อยู่ในความเปลี่ยนแปลงที่รู้จัก

เมื่อการถ่ายโอนหยุด ให้เปลี่ยนพารามิเตอร์ที่บันทึกไว้ทีละตัวและบันทึกขนาดที่ล้มเหลว ตรวจเส้นทางขากลับด้วย เพราะการเรียกซ้ำของเส้นทางแบบซ้อนกันสามารถเลียนแบบปัญหาขนาดแพ็กเก็ตได้ใกล้พอที่จะทำให้เสียเวลาทั้งบ่าย การตอบกลับ ICMP ที่ถูกกรองอาจซ่อนขีดจำกัดจริง โพรบจึงสำคัญกว่าการให้เหตุผล

เขียนงบประมาณไว้ตรงที่คนถัดไปจะหาเจอ

ตารางที่มีหนึ่งแถวต่อชั้นอยู่ได้นานกว่ากฎง่าย ๆ เก็บไว้ข้างแผนภาพทันเนล เพื่อไม่ให้ใครคำนวณซ้ำภายใต้แรงกดดัน

ทันเนลมากขึ้นหมายถึงการพึ่งพามากขึ้น แผนย้อนกลับจึงคู่ควรกับตำแหน่งข้างงบประมาณ หากตัวเลขยังไม่ลงตัว ให้วัดเส้นทางแทนการเดาอีกครั้ง เป้าหมายคือตัวเลขที่คุณปกป้องได้ ไม่ใช่ตัวเลขที่จำได้

บทความที่เกี่ยวข้อง