I worked around this issue by extending my connection protocol so that the multicast connect packet includes the interface index on which the packet was sent.
The server receiving the connect packet responds with a register connect packet which I have extended to include the interface index sent in the connect packet. When the client receives this packet it stores the interface index sent back as the one to use for further packets on that connection.
The server also needs to know which interface it is successfully sending on, so the register connect packet also includes the interface index used to send it. When the client receives this packet it responds with a confirm connect packet which includes the interface used by the server. When the server receives that packet it stores the interface index as the one to use for sending further packets to that client.
When building the list of possible interfaces to use I sort them into a priority order based on their names, giving higher priority to named interfaces which seem to be commonly used (like en0, wlan0, etc). I send the connect and register connect packets to each apparently viable interface at 50ms intervals starting with the higher priority interfaces. Generally the first in the list is the correct one, and the other side responds in much less than 50ms, so it becomes unnecessary to send the packets on the lower priority interfaces.
This is now working. It still feels like this is an extra set of hoops which I didn't have to jump through with IPv4, and that there ought to be a better way.