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

การทิ้ง การปฏิเสธ และการรีเซ็ตต่างกัน

กฎไฟร์วอลล์ที่ทิ้งทราฟฟิกจะโยนแพ็กเก็ตทิ้งและไม่ส่งอะไรกลับ ผู้ส่งจึงส่งซ้ำตามตัวจับเวลาของตนเอง กฎที่ปฏิเสธด้วย TCP reset จะปิดการเชื่อมต่อทันทีและแอปพลิเคชันเห็นข้อผิดพลาด kill switch ส่วนใหญ่เลือกทิ้ง เพราะการปฏิเสธจะเปิดเผยนโยบาย และเพราะการทิ้งคล้ายกับพฤติกรรมของเครือข่ายที่ตายแล้ว

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

แอปพลิเคชันทำอะไรระหว่างที่ช่วงขาดหายยังดำเนินอยู่

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

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

ตัดสินใจว่าจำเป็นต้องกู้คืนหรือไม่

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

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

ตรวจสอบการบล็อกและการกู้คืนแยกจากกัน

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

ss -tnp state established '( dport = :443 )'
sudo conntrack -L -p tcp --dport 443
sudo tcpdump -ni any 'tcp port 443 and tcp[tcpflags] & tcp-syn != 0'

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

เขียนพฤติกรรมที่คาดหวังไว้ข้างกฎการบังคับใช้และใส่วันที่ คนถัดไปที่เปลี่ยนกฎนั้นต้องรู้ว่าการติดตั้งสัญญาแบบใดไว้

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