NetKubeLab EN

Network Fundamental ที่อยู่และตัวตน

Multicast — ที่อยู่ที่ไม่ได้หมายถึงเครื่องไหนเลย

เครื่องที่คุณใช้อยู่เข้าร่วมกลุ่ม multicast อยู่แล้วหลายกลุ่มโดยไม่รู้ตัว และการแมปที่อยู่ของมันทิ้งข้อมูลไปห้าบิต

· หมวด 1 · ที่อยู่และตัวตน · 7 นาที

บทความ MAC address บอกว่าที่อยู่ ระดับเฟรมชี้ไปที่การ์ดใบหนึ่ง และบทความ โดเมนการชน บอกว่าที่อยู่แบบกระจายข่าว ชี้ไปที่ทุกคนในวง

Multicast คือช่องว่างระหว่างสองอย่างนั้น — ชี้ไปที่ "ใครก็ตามที่สนใจ" ซึ่ง เป็นที่อยู่ที่ไม่ได้หมายถึงเครื่องไหนเลยสักเครื่อง

ถ้ายังไม่เคยดู เริ่มตรงนี้

เครื่องคุณเข้าร่วมกลุ่มพวกนี้อยู่แล้ว

$ netstat -g

บนเครื่องที่ใช้เขียนบทนี้ ได้ที่อยู่ระดับเฟรมออกมาแบบนี้

  1:0:5e:0:0:1
  1:0:5e:0:0:fb
  33:33:0:0:0:1
  33:33:0:0:0:fb

สองบรรทัดแรกขึ้นต้นเหมือนกัน สองบรรทัดหลังก็ขึ้นต้นเหมือนกัน นั่นไม่ใช่เรื่อง บังเอิญ และเป็นเรื่องทั้งหมดของบทนี้

กฎการแมป — ที่อยู่ไอพีถูกยัดลงในที่อยู่ MAC

RFC 1112 ปี 1989 เขียนกฎไว้ประโยคเดียว

"An IP host group address is mapped to an Ethernet multicast address by placing the low-order 23-bits of the IP address into the low-order 23 bits of the Ethernet multicast address 01-00-5E-00-00-00 (hex)."

ที่อยู่ไอพี multicast ถูกตัดเหลือยี่สิบสามบิตท้าย แล้ววางลงในที่อยู่ MAC ที่ขึ้นต้นด้วย 01:00:5e

ผมลองคำนวณตามกฎนั้น

  224.0.0.1      ->  01:00:5e:00:00:01
  224.0.0.251    ->  01:00:5e:00:00:fb

สองบรรทัดนั้นตรงกับที่ netstat -g แสดงบนเครื่องจริงพอดี กฎที่เขียนไว้ปี 1989 คำนวณแล้วได้ค่าเดียวกับที่เครื่องรายงานวันนี้

ห้าบิตที่หายไป

ที่อยู่กลุ่มของ IPv4 มีส่วนที่ระบุกลุ่มได้ 28 บิต แต่กฎข้างบนแมปลงไปได้แค่ 23

  bits that identify the group   28
  bits carried into the MAC      23
  bits discarded                  5

ห้าบิตที่หายไปแปลว่ากลุ่มไอพีคนละกลุ่ม ได้ที่อยู่ MAC เดียวกัน กี่กลุ่ม คำนวณได้ตรง ๆ

  2^5 = 32 กลุ่ม ได้ MAC เดียวกัน

ผมลองคำนวณกลุ่มที่ชนกันจริง

  224.0.0.1      01:00:5e:00:00:01
  224.128.0.1    01:00:5e:00:00:01
  225.0.0.1      01:00:5e:00:00:01
  239.128.0.1    01:00:5e:00:00:01

สี่กลุ่มที่ต่างกันคนละเรื่อง ได้ที่อยู่ระดับเฟรมเดียวกัน ผลคือการ์ดเครือข่าย รับเฟรมของกลุ่มที่ตัวเองไม่ได้สนใจเข้ามาด้วย แล้วให้ระบบปฏิบัติการเป็นคนคัดทิ้ง

IPv6 แก้ปัญหานี้ด้วยการให้ที่มากขึ้น

RFC 2464 ระบุกฎของ IPv6 ไว้ว่า

"An IPv6 packet with a multicast destination address DST, consisting of the sixteen octets DST[1] through DST[16], is transmitted to the Ethernet multicast address whose first two octets are the value 3333 hexadecimal and whose last four octets are the"

  IPv4   01:00:5e   +  23 bits
  IPv6   33:33      +  32 bits

สามสิบสองบิตแทนที่จะเป็นยี่สิบสาม ซึ่งอธิบายว่าทำไมบรรทัดที่ขึ้นต้นด้วย 33:33 บนเครื่องผมถึงมีเลขท้ายยาวกว่า

ในทางทฤษฎีที่อยู่ IPv6 ยาว 128 บิต จึงยังชนกันได้อยู่ดี แต่ในทางปฏิบัติ 32 บิต ท้ายมักไม่ซ้ำกัน ปัญหาจึงแทบไม่เกิด

ทุกเครื่องต้องเข้าร่วมกลุ่มหนึ่งเสมอ

RFC 1112 กำหนดไว้ว่า

"every level 2 host must join the 'all-hosts' group (address 224.0.0.1) on each network interface at initialization time and must remain a member for as long as the host is active."

นั่นคือที่มาของ 1:0:5e:0:0:1 บนเครื่องผม ไม่มีใครตั้งค่าให้ มันเป็นข้อบังคับ ของมาตรฐาน

ส่วน 1:0:5e:0:0:fb มาจาก 224.0.0.251 ซึ่งเป็นกลุ่มที่เครื่องใช้ค้นหาบริการ ในวงเดียวกัน โดยไม่ต้องมีเซิร์ฟเวอร์กลาง

แล้วสวิตช์ทำอะไรกับมัน

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

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

โดยค่าเริ่มต้นสวิตช์กระจายเฟรม multicast ออกทุกพอร์ต ทั้งที่มีเครื่องเดียวที่สนใจ

RFC 4541 ระบุผลไว้ตรง ๆ

"Packets will be flooded into network segments where no node has any interest in receiving the packet."

และเสริมว่าผลกระทบไม่ได้อยู่ที่ภาระของเครื่องที่ไม่สนใจเท่านั้น

"While nodes will rarely incur any processing overhead to filter packets addressed to unrequested group addresses, they are unable to transmit new packets onto the shared media for the period of time that the multicast packet is flooded."

เครื่องที่ไม่สนใจไม่ได้เสียแรงประมวลผลมาก แต่เสียโอกาสในการส่ง ซึ่งเป็น ตรรกะเดียวกับเรื่องเวลาออกอากาศในบทความ Wi-Fi

IGMP snooping — และคำเตือนที่ตรงไปตรงมาผิดปกติ

ทางแก้คือให้สวิตช์แอบฟังข้อความที่เครื่องใช้บอกว่าตัวเองเข้าร่วมกลุ่มไหน แล้วส่ง เฉพาะพอร์ตนั้น

สวิตช์ที่แอบฟังการเข้าร่วมกลุ่ม ส่งเฉพาะพอร์ตที่มีเครื่องสนใจจริง ส่วนพอร์ตอื่นไม่ได้รับ

แต่ RFC 4541 เขียนประโยคที่เอกสารมาตรฐานไม่ค่อยเขียนกัน

"Many switch datasheets state support for IGMP snooping, but no recommendations for this exist today."

เอกสารกำลังบอกว่าผู้ผลิตอ้างว่ารองรับฟีเจอร์ที่ยังไม่มีข้อกำหนดว่าต้องทำอะไร และเอกสารฉบับนั้นเองคือความพยายามเขียนข้อกำหนดขึ้นมา

นั่นแปลว่าคำว่า IGMP snooping บนแผ่นสเปกของสองยี่ห้อ อาจไม่ได้หมายถึงพฤติกรรม เดียวกัน

เมื่อมันโกหก

"multicast ประหยัดกว่ากระจายข่าวเสมอ" ประหยัดก็ต่อเมื่อสวิตช์กรองให้จริง ถ้าไม่ทำ มันคือกระจายข่าวที่มีชื่ออื่น

"ที่อยู่ multicast คือที่อยู่ของกลุ่มเครื่อง" มันคือที่อยู่ของ กลุ่ม ไม่ใช่ของเครื่อง ไม่มีเครื่องไหนเป็นเจ้าของ และไม่เคยปรากฏเป็นที่อยู่ต้นทาง

"เครื่องผมไม่ได้ใช้ multicast" netstat -g จะบอกว่าใช้อยู่ และหนึ่งในกลุ่ม นั้นเป็นข้อบังคับตาม RFC 1112

"MAC ของ multicast ระบุกลุ่มได้" ระบุได้ไม่ครบ ห้าบิตหายไปในการแมป กลุ่มไอพี 32 กลุ่มจึงได้ MAC เดียวกัน

"เปิด IGMP snooping แล้วเหมือนกันทุกยี่ห้อ" RFC 4541 ระบุเองว่าไม่มีข้อกำหนด มาก่อนหน้านั้น

ตัวอย่างจริงจากงานจริง

กรณีที่ 1 — ดูว่าเครื่องเราอยู่กลุ่มไหนบ้าง

คำสั่ง

$ netstat -g

อ่านอย่างไร ที่อยู่ที่ขึ้นต้น 1:0:5e คือกลุ่มของ IPv4 ส่วน 33:33 คือของ IPv6 ถ้าเห็นกลุ่มที่ไม่คาดคิด ให้ย้อนกลับไปดูว่าโปรแกรมไหนเข้าร่วมไว้

สิ่งที่ยังไม่ได้พิสูจน์ รายการนี้บอกว่าอินเทอร์เฟซตั้งใจรับกลุ่มไหน ไม่ได้ บอกว่ามีทราฟฟิกของกลุ่มนั้นวิ่งอยู่จริง

กรณีที่ 2 — ทราฟฟิก multicast ท่วมวง

สถานการณ์ มีระบบที่ใช้ multicast แล้วเครื่องที่ไม่เกี่ยวข้องช้าลงไปด้วย

อ่านอย่างไร ตรวจว่าสวิตช์กรองให้หรือกระจายทุกพอร์ต ถ้ากระจาย เครื่องทุกตัว ในโดเมนกระจายข่าวจะเสียโอกาสส่งตามที่ RFC 4541 อธิบาย

สิ่งที่ยังไม่ได้พิสูจน์ การเปิด snooping มักช่วย แต่พฤติกรรมจริงต่างกันตาม ยี่ห้อ ซึ่งเอกสารมาตรฐานเองก็ยอมรับ

กรณีที่ 3 — สองกลุ่มรบกวนกันทั้งที่ไม่เกี่ยวข้อง

สถานการณ์ ตั้งกลุ่มใหม่แล้วเครื่องที่ฟังอีกกลุ่มได้รับของที่ไม่ควรได้

อ่านอย่างไร คำนวณที่อยู่ MAC ของทั้งสองกลุ่มด้วยกฎ 23 บิต ถ้าได้ค่าเดียวกัน นั่นคือการชนที่อธิบายไว้ข้างบน วิธีแก้คือเลือกที่อยู่กลุ่มที่ 23 บิตท้ายไม่ซ้ำกัน

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

สิ่งที่ที่อยู่แบบนี้สอน

Unicast ตอบคำถามว่า "ส่งให้ใคร" ส่วน broadcast ตอบว่า "ส่งให้ทุกคน"

Multicast ตอบคำถามที่ยากกว่าทั้งสองอัน คือ "ส่งให้คนที่สนใจ" ซึ่งแปลว่าต้องมี ใครสักคนรู้ว่าใครสนใจ และข้อมูลนั้นไม่ได้อยู่ในที่อยู่

นั่นคือเหตุผลที่ multicast ต้องมีโพรโทคอลเสริมสำหรับบอกว่าใครเข้าร่วมกลุ่มไหน และเหตุผลที่มันทำงานได้ดีหรือแย่ ขึ้นกับว่าอุปกรณ์ระหว่างทางฟังคำบอกนั้นหรือเปล่า

อ้างอิง

เอกสารมาตรฐาน

  • RFC 1112 สิงหาคม 1989 Host Extensions for IP Multicasting — กฎการแมป 23 บิต และข้อบังคับให้ทุก เครื่องเข้าร่วมกลุ่ม 224.0.0.1
  • RFC 2464 ธันวาคม 1998 Transmission of IPv6 Packets over Ethernet Networks — กฎ 33:33 ของ IPv6
  • RFC 4541 พฤษภาคม 2006 Considerations for IGMP and MLD Snooping Switches — ผลของการกระจายทุกพอร์ต และประโยคเรื่องแผ่นสเปกที่ยกมาอ้าง

วัดจากเครื่องที่ใช้เขียน

  • netstat -g แสดงกลุ่มที่อินเทอร์เฟซเข้าร่วมอยู่จริง ทั้งที่ขึ้นต้นด้วย 1:0:5e และ 33:33

คำนวณเอง

  • การแมปที่อยู่ไอพีเป็น MAC ตามกฎ 23 บิตของ RFC 1112 และการนับว่ากลุ่มไอพีกี่ กลุ่มได้ MAC เดียวกัน คำนวณจากจำนวนบิตที่หายไป

วัดจากเครื่องจริงคำนวณเอง

อ่านหน้านี้เป็นภาษาอังกฤษ