-C
ตัวเลือกใหม่ไม่เป็นที่พอใจเนื่องจากเปิดให้เข้ากับสภาพการแข่งขันแบบเวลาเช็คอินต่อเวลา (TOCTTOU) หากทั้งสองกระบวนการพยายามที่จะเพิ่มกฎเดียวกันในเวลาเดียวกัน-C
จะไม่ปกป้องพวกเขาจากการเพิ่มสองครั้ง
ดังนั้นมันจึงไม่ดีไปกว่าการgrep
แก้ปัญหา งานการประมวลผลข้อความที่แม่นยำบนเอาต์พุตiptables-save
สามารถทำงานได้อย่างน่าเชื่อถือ-C
เนื่องจากเอาต์พุตนั้นเป็นสแน็ปช็อตที่เชื่อถือได้ของสถานะของตาราง
สิ่งที่จำเป็นต้องมีคือ--ensure
ตัวเลือกที่จะตรวจสอบและเพิ่มกฎต่อเมื่อไม่มีกฎอยู่แล้ว ยิ่งไปกว่านั้นมันจะดีถ้ากฎถูกย้ายไปยังตำแหน่งที่ถูกต้องซึ่งจะมีการแทรกกฎใหม่หากไม่มีอยู่แล้ว ( --ensure-move
) ตัวอย่างเช่นหากiptables -I 1
ใช้เพื่อสร้างกฎที่ส่วนหัวของห่วงโซ่ แต่กฎนั้นมีอยู่แล้วในตำแหน่งที่เจ็ดจากนั้นกฎที่มีอยู่ควรย้ายไปยังตำแหน่งแรก
หากไม่มีคุณสมบัติเหล่านี้ฉันคิดว่าวิธีแก้ปัญหาที่เป็นไปได้คือการเขียน shell script loop โดยใช้โค้ดหลอกนี้:
while true ; do
# delete all copies of the rule first
while copies_of_rule_exist ; do
iptables -D $RULE
done
# now try to add the rule
iptables -A $RULE # or -I
# At this point there may be duplicates due to races.
# Bail out of loop if there is exactly one, otherwise
# start again.
if exactly_one_copy_of_rule_exists ; then
break;
fi
done
รหัสนี้สามารถหมุนไปรอบ ๆ ; ไม่รับประกันว่าจะมีนักแข่งสองคนหรือมากกว่านั้นออกซ้ำภายในจำนวนครั้งที่แน่นอน สามารถเพิ่มการ backoff แบบเอ็กซ์โปเนนเชียลแบบสุ่มบางอย่างเพื่อช่วยในเรื่องนั้น