5

I have a small app that is running two threads.

One thread sends a UDP multicast packet (to group 239.0.0.1), and the other reads that same multicast packet.

When I run this on app on Windows using Visual Studio, it works - the packet is successfully sent and received. I see it on Wireshark. I also have an embedded target where this app ultimately runs, running VxWorks RTOS, and it works on VxWorks as well.

I tried it on Linux using WSL2. The sendto() is successful, but the recvfrom() fails. However I do see the packet on Wireshark, and there are no errors reported on Wireshark.

I downgraded to WSL1 and it works.

Is there something specific to WSL2 that might cause multicast to fail, but work on WSL1, Windows and VxWorks? If I switch to unicast, it works on WSL2.

Here are some code snippets:

Receive thread:

uint32_t  ip_addr_mgrp;
uint32_t  ip_addr_mifc;
inet_pton(AF_INET, (char*)"172.18.19.53", &ip_addr_mifc);
inet_pton(AF_INET, (char*)"239.0.0.1", &ip_addr_mgrp);

int fd = socket(AF_INET, SOCK_DGRAM, SOCKET_PROTOCOL);

struct sockaddr_in server_addr;

server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = ip_addr_mifc;
server_addr.sin_port = htons(45007);

bind(fd, (struct sockaddr*)&server_addr, sizeof(server_addr));

struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = ip_addr_mgrp;
mreq.imr_interface.s_addr = ip_addr_mifc;

setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mreq, sizeof(mreq));

// code to set to non-blocking

// Loop for reading

// Call select()
// Call FD_ISSET()
// Call recvfrom()

TX thread:

uint32_t  ip_addr_mgrp;
uint32_t  ip_addr_mifc;
inet_pton(AF_INET, (char*)"172.18.19.53", &ip_addr_mifc);
inet_pton(AF_INET, (char*)"239.0.0.1", &ip_addr_mgrp);

int fd = socket(AF_INET, SOCK_DGRAM, SOCKET_PROTOCOL);

struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = ip_addr_mgrp;
mreq.imr_interface.s_addr = ip_addr_mifc;

setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mreq, sizeof(mreq));

setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (const char*)&mreq.imr_interface.s_addr, sizeof(struct in_addr));

char loop = 1;
setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, (char*)&loop, sizeof(loop));

// code to set to non-blocking

// Loop for sending

// Call sendto() to 237.0.0.1:45007
4
  • You're not checking the return from bind. Did it succeed? With WSL2, is there a windows firewall preventing the linux VM from getting out? Commented Oct 30, 2024 at 0:39
  • I omitted some of the code for brevity - in this case, I left out all the return code checking. I have checks for every call (socket, bind, setsocketopt, etc) and they are all passing. In this case, there's no traffic that would be leaving WSL - the app is sending UDP back to itself (kinda silly for now, but it's a starting point). Commented Oct 30, 2024 at 1:07
  • Random thoughts ... As you probably know, WSL1 and WSL2 are different. WSL1 [IIRC] is just a syscall interface under windows. But, WSL2 is a hypervisor that allows a [true] linux system to run under a VM. For linux, consider starting with an interface name (e.g. eth0) instead of a hardwired IP address to get ip_addr_mifc Or, consider using htonl(INADDR_ANY) for the interface address!?!? What is SOCKET_INTERFACE? I've used socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP) Use SO_REUSEADDR? Use the multicast IP for bind??? Commented Oct 30, 2024 at 1:50
  • bind to 'all interfaces' with INADDR_ANY address or to the multicast group to make sure multicast traffic gets to the socket. Binding to the interface address permits UDP unicast traffic in Commented Oct 30, 2024 at 8:43

1 Answer 1

1

On Linux, if a socket is bound to a local IP address, it won't be able to receive multicast traffic even if the multicast group is joined.

As mentioned in the comments, WSL1 is an API layer over the Windows syscalls while WSL2 is a full Linux virtual machine. This is why binding to a local interface works on WSL1 but not on WSL2.

You can fix this by either binding the socket to INADDR_ANY or to the multicast address in question (239.0.0.1 in this case).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.