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

MTU ของเส้นทางวัดอะไรกันแน่

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

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

ทำไมอุโมงค์จึงลดขนาดแพ็กเก็ตที่ใช้งานได้

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

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

การค้นหาทำงานได้เมื่อข้อมูลตอบกลับมาถึง

การค้นหา IPv4 อาศัยบิต don't-fragment เราเตอร์ที่ไม่สามารถส่งต่อแพ็กเก็ตได้จะคืน ICMP fragmentation-needed พร้อม MTU ของฮอปถัดไป และผู้ส่งจะลดการประมาณลง IPv6 ใช้ข้อความ Packet Too Big แทน เพราะเราเตอร์ไม่แบ่งระหว่างทาง ทั้งสองกลไกสันนิษฐานว่าข้อความจะหาทางกลับไปถึงผู้ส่ง ผ่านอุโมงค์และผ่านไฟร์วอลล์ใด ๆ บนเส้นทางขากลับ เมื่อข้อสันนิษฐานนั้นล้มเหลว ผู้ส่งจะพยายามขนาดที่เส้นทางรับไม่ได้ซ้ำแล้วซ้ำอีก

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

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

ทดสอบเส้นทางแทนการเดาตัวเลข

ตรึงปลายทาง เครือข่ายการเข้าถึง และอุโมงค์ไว้ แล้วเปลี่ยนเฉพาะขนาดแพ็กเก็ต การทดสอบ don't-fragment ที่ล้มเหลวพร้อมคำใบ้ MTU ให้ขีดจำกัดของฮอปถัดไป ทำซ้ำจนกว่าขนาดหนึ่งจะผ่าน และบันทึกทั้งขนาดและตระกูลที่อยู่

ping -M do -s 1400 10.60.20.10
ping -M do -s 1300 10.60.20.10
ping -6 -M do -s 1300 2001:db8::10

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

PLPMTUD ที่อธิบายใน RFC 4821 ทดสอบขึ้นด้านบนและใช้การตอบรับของทรานสปอร์ตแทนการเชื่อมั่นในข้อผิดพลาดที่ส่งมา ช่วยบนเส้นทางที่กรอง ICMP แต่การสนับสนุนแตกต่างกันตามสแตกและแอปพลิเคชัน สตรีม TCP อาจฟื้นตัวได้เอง ขณะที่แอปพลิเคชัน UDP ที่มีขนาดดาตาแกรมคงที่ยังคงล้มเหลว

เลือกค่าและบันทึกเหตุผล

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

กลไก IPv4 อธิบายไว้ใน RFC 1191 และแนวทางแพ็กเก็ตไนซ์ IPv6 ใน RFC 8201 การระบุทั้งสองช่วยไม่ให้นักวิศวกรคนต่อไปต้องอนุมานใหม่ ถ้าการถ่ายโอนยังค้างที่ขนาดที่คุณเลือก ให้หยุดลดตัวเลขและดูชั้นถัดไป เส้นทางที่ล้มเหลวทุกขนาดไม่ใช่ปัญหา MTU

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