Skip to content

Unable to join multicast groups on macOS or iOS with a specified port #107508

Open
@nstod

Description

@nstod

Tested versions

  • Reproducible in 4.0, 4.4.1, 4.5-dev5

System information

Godot v4.5.dev5 - macOS Sequoia (15.5.0) - Multi-window, 1 monitor - OpenGL 3 (Compatibility) - Apple M2 Max - Apple M2 Max (12 threads)

Issue description

When using PacketPeerUDP, calling bind(port) followed by join_multicast_group(address, if_name) will fail on macOS and iOS (tested on iOS 18.5) with the error below:

E 0:00:00:373   node_2d.gd:21 @ _ready(): Condition "ret != 0" is true. Returning: FAILED
  <C++ Source>  drivers/unix/net_socket_unix.cpp:230 @ _change_multicast_group()
  <Stack Trace> node_2d.gd:21 @ _ready()

And my log output using the minimal reproduction below:
Failed to bind to multicast on en0: 1

If you reverse the order and call join_multicast_group followed by bind, you get this error output:

E 0:00:00:368   node_2d.gd:14 @ _ready(): Condition "_sock->is_open()" is true. Returning: ERR_ALREADY_IN_USE
  <C++ Source>  core/io/packet_peer_udp.cpp:182 @ bind()
  <Stack Trace> node_2d.gd:14 @ _ready()

And the log output:
Failed to bind to port: 22

If you just call join_multicast_group without bind, it works, but then you end up with a random port, which does not work with multicast, since it's an address:port combination.

Steps to reproduce

Here is a minimal reproduction. Note that attempting to call join_multicast_group before bind on the socket will allow join_multicast_group to succeed, but bind fails.

extends Node2D

func _ready() -> void:
	const MULTICAST_ADDRESS = "239.255.0.55"
	const MULTICAST_PORT = 35757
	var discovery_socket = PacketPeerUDP.new()
	var error = discovery_socket.bind(MULTICAST_PORT)
	if error != OK:
		discovery_socket = null
		print("Failed to bind to port: %s" % error)
		return
	for interface in IP.get_local_interfaces():
		var interface_name = interface["name"]
		var addresses = interface["addresses"] as Array[String]
		if addresses.any(func(a: String): return not a.contains(":")):
			var join_error = discovery_socket.join_multicast_group(MULTICAST_ADDRESS, interface_name)
			if join_error != OK:
				print("Failed to bind to multicast on %s: %s" % [interface_name, join_error])

Minimal reproduction project (MRP)

networking-repro.zip

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    For team assessment

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions