Skip to content

Allow selecting the interface for Multicast in PacketPeerUDP#118964

Open
NoNormalDev wants to merge 1 commit into
godotengine:masterfrom
NoNormalDev:edit1
Open

Allow selecting the interface for Multicast in PacketPeerUDP#118964
NoNormalDev wants to merge 1 commit into
godotengine:masterfrom
NoNormalDev:edit1

Conversation

@NoNormalDev
Copy link
Copy Markdown
Contributor

@NoNormalDev NoNormalDev commented Apr 26, 2026

Summary of changes

Added the function set_multicast_send_interface(if_name) to PacketPeerUDP and NetSocket.
This allows controlling the interface, through which a packet is sent to a multicast address.
Before, the OS would choose an interface, so that the packet can reach it, but since it is a multicast address, it would choose a random one (so for example localhost or dummy0), which is useless, because the address can be reached using any interface.
Internally, this sets IPV6_MULTICAST_IF and/or IP_MULTICAST_IF using setsockopt(...).

Example usage

This allows sending packets to multicast addresses using all interfaces:
image

Motivation

This is an implementation of godotengine/godot-proposals#3109
Also, I myself have had the same problem with multicast, so I decided to fix it.
Without this, functions like join_mutlicast_group in Godot are a bit (or a lot) useless, because the interface choices by the OS aren't consistent.

Technical overview

The user calls set_mutlicast_send_interface(interface_name) on the PacketPeerUDP, which will pass the argument to the underlaying NetSocket. Each platform group (Unix, Windows), then defines that function in its own way, but the main priciple is the same:
If the socket ip_type covers IPv6, we find the interface index and call setsockopt(_sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, ...) with it.
If the socket ip_type covers IPv4, we find the first IPv4 address in the interface and call setsockopt(_sock, IPPROTO_IP, IP_MULTICAST_IF, ...) with it.

Testing

I have tested it, these connections worked first try (aside from firewall config):

  1. Localhost (Almost any interface works locally)
  2. Windows - WSL (Linux), using vEthernet (Hyper-V connection)
  3. Windows - Windows, using Wi-Fi
  4. Windows - Android, using Wi-Fi
  5. Android - Android, using Wi-Fi
  6. Windows - Ubuntu VM (VMWare Drivers)

Discussion

I am not sure if it works on iOS and MacOS, so testing with it could be good.

AI Self Disclosure

The setsockopt(...) lines were written by Claude. I made sure that the code makes sense, is readable and actually works, which means that I made changes to it.

TODO (for myself)

  • Move if_index into IPv6 if statement (Awaiting push)
  • Return early for IPv4 (Awating push)
  • Add tests confirming DWORD and struct in_addr are 4 bytes.
  • Test with native Linux

@NoNormalDev NoNormalDev requested review from a team as code owners April 26, 2026 12:21
@AThousandShips
Copy link
Copy Markdown
Member

The AI created the main code, while I implemented it in a way, that is readable and human.

I'm not sure what is meant by this, do you mean you took inspiration from it and implemented it yourself, or that you rewrote it to look less "AI"?

I understand that the use of AI is bad, but I really spent a lot of time creating this, would be sad if this is the reason this doesn't get merged.

I understand your position, but I hope you understand we also value human contributions and code that was done responsible effort, and the best way to get your contribution merged would be to spend the time to understand the problem and write the code yourself

Comment thread core/io/packet_peer_udp.cpp Outdated
@NoNormalDev
Copy link
Copy Markdown
Contributor Author

The AI created the main code, while I implemented it in a way, that is readable and human.

I'm not sure what is meant by this, do you mean you took inspiration from it and implemented it yourself, or that you rewrote it to look less "AI"?

I understand that the use of AI is bad, but I really spent a lot of time creating this, would be sad if this is the reason this doesn't get merged.

I understand your position, but I hope you understand we also value human contributions and code that was done responsible effort, and the best way to get your contribution merged would be to spend the time to understand the problem and write the code yourself

To clear up, the AI told me what are the parameters (and its types) of setsockopt should be (it is a little bit diffrent for unix/windows), while I wrote the code.

@AThousandShips
Copy link
Copy Markdown
Member

I'm confused, that's not what you said? You said it "created the main code", and you say you "I have put extra effort to understand what the code does and to fix possible problems.", do you mean understand your own code that you wrote?

@NoNormalDev
Copy link
Copy Markdown
Contributor Author

I'm confused, that's not what you said? You said it "created the main code", and you say you "I have put extra effort to understand what the code does and to fix possible problems.", do you mean understand your own code that you wrote?

Yes, because what if the AI lied about the parameters, so I made sure it made sense. The "main code" part is the setsockopt.

@AThousandShips
Copy link
Copy Markdown
Member

AThousandShips commented Apr 26, 2026

So what code specifically was written by the LLM? Just for clarity, and why was the LLM needed to write any of the code if you understand it

@NoNormalDev
Copy link
Copy Markdown
Contributor Author

So what code specifically was written by the LLM? Just for clarity, and why was the LLM needed to write any of the code if you understand it

setsockopt(_sock, IPPROTO_IP, IP_MULTICAST_IF, (char *)&addr, sizeof(addr))
setsockopt(_sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char *)&if_index, sizeof(if_index)) != 0)
setsockopt(_sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, &if_index, sizeof(if_index))
setsockopt(_sock, IPPROTO_IP, IP_MULTICAST_IF, &addr, sizeof(addr))

Well the LLM was needed because I didn't know how to use the setsockopt, and how to properly pass the types (= how to properly write the (char *)& and so on). The LLM first wrote it, I understood it, and used that knowledge to put it into the code (but the lines above were copied directly).

@AThousandShips
Copy link
Copy Markdown
Member

I would suggest looking up those methods online in their documentation and validating the output instead of using the LLM for this, it's far more reliable I would say

@Chaosus Chaosus added this to the 4.x milestone Apr 26, 2026
@NoNormalDev NoNormalDev changed the title Networking: Allow selecting the interface for Multicast in PacketPeerUDP Allow selecting the interface for Multicast in PacketPeerUDP Apr 26, 2026
@NoNormalDev NoNormalDev force-pushed the edit1 branch 2 times, most recently from d0771e5 to 6b49371 Compare May 12, 2026 12:01
@NoNormalDev
Copy link
Copy Markdown
Contributor Author

NoNormalDev commented May 12, 2026

Removed the accidental sync and squashed my original 10 commits toghether, since in the docs it says, that that is the preferred way.

@NoNormalDev NoNormalDev changed the title Allow selecting the interface for Multicast in PacketPeerUDP Allow selecting the interface for Multicast in PacketPeerUDP May 15, 2026
@NoNormalDev NoNormalDev force-pushed the edit1 branch 2 times, most recently from 9a90727 to 2726851 Compare June 1, 2026 18:01
Comment thread drivers/windows/net_socket_winsock.cpp Outdated
Comment thread drivers/unix/net_socket_unix.cpp Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants