Skip to content

IPv4 Multicast Sockets Will Only Receive IP_MULTICAST_LOOP Enabled Packets When The Port is Either 5353 or 4444 #28

@amydevs

Description

@amydevs

Describe the bug

IPv4 Multicast Sockets will only receive IP_MULTICAST_LOOP enabled packets when the port is Either 5353 or 4444.
I'm not sure if there is something wrong with my socket setup code, but it should be basically the minimal example below.

To Reproduce

With MDNS

describe(MDNS.name, () => {
  let mdns1: MDNS;
  let mdns2: MDNS;

  beforeEach(async () => {
    mdns1 = new MDNS();
    mdns2 = new MDNS();
  });
  afterEach(async () => {
    await mdns1.stop();
    await mdns2.stop();
  });
  test('advertisement', async () => {
    const mdnsPort = 1234 as Port;
    const mdns1Hostname = 'polykey1' as Hostname;
    const mdns2Hostname = 'polykey2' as Hostname;
    await mdns1.start({ hostname: mdns1Hostname, port: mdnsPort });
    await mdns2.start({ hostname: mdns2Hostname, port: mdnsPort });
    const service = {
      name: 'test',
      port: mdnsPort,
      protocol: 'udp',
      type: 'polykey',
    } as Parameters<typeof MDNS.prototype.registerService>[0];
    mdns2.registerService(service);
    await new Promise((resolve, reject) => {
      mdns1.addEventListener(
        events.EventMDNSService.name,
        (e: events.EventMDNSService) => {
          console.log(e.detail.hosts)
          // only 127.0.0.1 will show up, meaning that none of the other ipv4 bound sockets received the message
          try {
            expect(e.detail.name).toBe(service.name);
            expect(e.detail.port).toBe(service.port);
            expect(e.detail.protocol).toBe(service.protocol);
            expect(e.detail.type).toBe(service.type);
            expect(e.detail.hostname).toBe(mdns2Hostname + '.local');
            resolve(null);
          } catch (e) {
            reject(e);
          }
        },
      );
    });
  });
});

Minimal Example

import * as dgram from 'dgram';
describe('', () => {
  test('', () => {
    const iface = '172.19.207.91';
    const group = '224.0.0.251';
    const port = 1234;
    const s1 = dgram.createSocket({
      type: 'udp4',
      reuseAddr: true,
    });
    s1.addListener('message', (msg) => {
      console.log(msg.toString());
      // nothing will ever be logged
    });
    s1.bind(port, group, () => {
      s1.addMembership(group, iface);
      s1.setMulticastInterface(iface);
      s1.setMulticastLoopback(true);
      s1.setMulticastTTL(255);

      const s2 = dgram.createSocket({
        type: 'udp4',
        reuseAddr: true,
      });

      s2.bind(port, group, () => {
        s2.addMembership(group, iface);
        s2.setMulticastInterface(iface);
        s2.setMulticastLoopback(true);
        s2.setMulticastTTL(255);
        s2.send('123', port, group);
      });
    });
  })
})

In both cases, when port is set to 4444 or 5353. The expected results will occur, which is that the packet is received from the non-loopback interface, and that the MDNS instance will be able to find the non-loopback ipv4 address on the service.

Expected behavior

The packet is received from the non-loopback interface, and that the MDNS instance will be able to find the non-loopback ipv4 address on the service.

Screenshots

Platform (please complete the following information)

  • Device: Dell Precision 3470
  • OS: NixOS
  • Version: Node v20.5.1

Additional context

Notify maintainers

@amydevs

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingr&d:polykey:core activity 4End to End Networking behind Consumer NAT Devices

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions