dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
14.95k stars 4.65k forks source link

Cannot Send to a broadcastable socket on iOS 17 device #106588

Open amp64 opened 3 weeks ago

amp64 commented 3 weeks ago

Description

If you try and Send a Broadcast to a socket it will fail on iOS 17 devices with the error "no route to host". I believe this is due to the flag IP_BOUND_IF missing, described here: https://developer.apple.com/forums/thread/658518?answerId=631476022#631476022

Reproduction Steps

        private static async Task TestBroadcastAsync()
        {
            try
            {
                IPAddress localIP;
                using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0))
                {
                    socket.Connect("8.8.8.8", 65530);
                    IPEndPoint endPoint = socket.LocalEndPoint as IPEndPoint;
                    localIP = endPoint.Address;
                }

                bool multicast = false;

                using (var socket = new Socket(localIP.AddressFamily, SocketType.Dgram, ProtocolType.Udp))
                {
                    if (!multicast)
                    {
                        socket.EnableBroadcast = true;
                    }
                    socket.ExclusiveAddressUse = false;

                    var dest = new IPEndPoint(IPAddress.Broadcast, 1900);
                    socket.Bind(new IPEndPoint(localIP, 0));
                    Debug.WriteLine($"Test-Bound ok to {localIP}");

                    var bytes = new ArraySegment<byte>(new byte[1]);
                    await socket.SendToAsync(bytes, SocketFlags.None, dest);
                }
            } 
            catch (Exception ex)
            {
               Debug.WriteLine("Exception: " + ex.Message);
            }
        }

Expected behavior

The Send to work

Actual behavior

"No route to host" exception.

Regression?

Unknown. This does work on iOS 15 devices, and iOS 17 simulators.

Known Workarounds

No response

Configuration

iPhone SE 3, iOS 17.5.1, .NET 8 (and 7)

Other information

No response

amp64 commented 3 weeks ago

Update, I was mistaken about one of my phones: This affects iOS 16 as well, on all devices I have tried. It is fine on iOS 15.3 devices.

matouskozak commented 1 week ago

Update, I was mistaken about one of my phones: This affects iOS 16 as well, on all devices I have tried. It is fine on iOS 15.3 devices.

@amp64 could you please share what exact version of .NET 8 are using (dotnet --info)? Also are you using a MAUI app or plain dotnet new ios app?

I tried you repro locally with latest .NET 8 servicing release (8.0.8), iPhone 11 with iOS 17.5.1 and the code worked correctly (i.e., it reported "Bound ok")

amp64 commented 1 week ago

Dumb question but how do I determine the exact version of dotnet on my iPhone? dotnet --version on my PC says 8.0.6, my PC has the 8.0.302 NET SDK from VS installed. I am using Avalonia 11.1.2 to x-target iOS.

In the logs the closest I see to a version is Microsoft.iOS.Sdk/17.2.8053

In Solution Explorer if I click under Frameworks I see 8.0.624.26715, so it seems like I need to update this.

amp64 commented 1 week ago

Sorry I have done a poor job with the repro here. I was thinking the error was from the Bind, but its actually in the subsequent SendTo. Add this:

var remoteIP = IPAddress.Parse("239.255.255.250");
var dest = new IPEndPoint(remoteIP, 1900);
await socket.SendToAsync(buff, SocketFlags.None, dest);
matouskozak commented 1 week ago

Dumb question but how do I determine the exact version of dotnet on my iPhone? dotnet --version on my PC says 8.0.6, my PC has the 8.0.302 NET SDK from VS installed. I am using Avalonia 11.1.2 to x-target iOS.

In the logs the closest I see to a version is Microsoft.iOS.Sdk/17.2.8053

In Solution Explorer if I click under Frameworks I see 8.0.624.26715, so it seems like I need to update this.

Not a dumb question at all. Running dotnet --info on your PC should give you all necessary information: runtime, SDK and iOS workload versions. Basically, all the things that you mentioned in your comment.

matouskozak commented 1 week ago

Sorry I have done a poor job with the repro here. I was thinking the error was from the Bind, but its actually in the subsequent SendTo. Add this:

var remoteIP = IPAddress.Parse("239.255.255.250");
var dest = new IPEndPoint(remoteIP, 1900);
await socket.SendToAsync(buff, SocketFlags.None, dest);

No problem, could you please update the repro example and I'll check it out.

amp64 commented 1 week ago

I updated the description and the repro to improve usefulness and accuracy.

vitek-karas commented 1 week ago

I'm marking these as 10.0 - as the priority is not that high. Once we figure out the real issue we can consider backporting to 9 as necessary.

matouskozak commented 1 week ago

I updated the description and the repro to improve usefulness and accuracy.

Can confirm that the new repro reproduces inside dotnet new ios sample app on iOS 17.5.1 device.