Bug 45364 - SocketException when call Socket.IOControl
Summary: SocketException when call Socket.IOControl
Status: RESOLVED NOT_ON_ROADMAP
Alias: None
Product: Runtime
Classification: Mono
Component: io-layer ()
Version: 4.6.0 (C8)
Hardware: PC Linux
: --- normal
Target Milestone: ---
Assignee: Ludovic Henry
URL:
Depends on:
Blocks:
 
Reported: 2016-10-13 15:06 UTC by Mario Jungwirth
Modified: 2017-07-07 20:10 UTC (History)
4 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
Example programm that demonstrate the exception (1.34 KB, text/plain)
2016-10-13 15:06 UTC, Mario Jungwirth
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED NOT_ON_ROADMAP

Description Mario Jungwirth 2016-10-13 15:06:37 UTC
Created attachment 18021 [details]
Example programm that demonstrate the exception

I call IOControl with IOControlCode.RoutingInterfaceQuery to determine routing information. 

On Windows with MS-.Net i get the correct information.
On Linux with Mono 4.4.0 i get e SocketException with a dubious message:

"System.Net.Sockets.SocketException: The descriptor is not a socket"

I have attached a sample Program that show the error
You must set ip/port to connect to (telnet service, web, ....)
I think this is a wrong implementation in mono.
Comment 1 Mario Jungwirth 2016-10-18 05:49:35 UTC
I have testet with mono 4.4.0 and 4.6.1. same result.
Comment 2 Ludovic Henry 2017-04-03 16:04:51 UTC
Hi Mario, I tried with master and cannot reproduce it. Could you please confirm if you can reproduce with mono 4.8.0? Thank you.
Comment 3 H3V2 2017-04-21 04:15:49 UTC
I'm on Mono JIT compiler version 4.8.1 (Stable 4.8.1.0/22a39d7 Wed Apr 12 12:00:40 UTC 2017)

I've just tested Mario's program and can confirm the output is as reported.

The descriptor is not a socket
[ERROR] FATAL UNHANDLED EXCEPTION: System.Net.Sockets.SocketException (0x80004005): The descriptor is not a socket


I believe the problem is that Linux does not expose a comparable syscall which accepts a RoutingInterfaceQuery IOCTL. This is Windows specific control code.

An end-user would rely on the iproute2 package to find the ip address of the gateway exposing a route to a given destination

$ ip route get 74.125.137.100

But as you can see from the iproute_get() function in iproute2's source code https://github.com/shemminger/iproute2/blob/707f612c00a91fe3c17d7af5319e423545a496c5/ip/iproute.c it involves several syscalls, not one clean RoutingInterfaceQuery request.

I don't know if anybody will find it useful, but short of the Mono team implementing a comparable API, you can bind a datagram Socket and Connect() to the address that you would have passed into RoutingInterfaceQuery.

Read the LocalEndPoint off the Socket to get your route.


    private static IPAddress GetRouteLinux(IPAddress destionationIpAddress)
    {
        try
        {
        using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0))
        {
            socket.Connect(destionationIpAddress, 443);
            return ((IPEndPoint) socket.LocalEndPoint).Address;
        }
        }
        catch (Exception ex)
        {
        Log.Error(ex);
        }

        return null;
    }
Comment 5 Ludovic Henry 2017-07-07 20:10:20 UTC
As pointed out in https://bugzilla.xamarin.com/show_bug.cgi?id=45364#c3 this feature is not readily available on Linux, and a workaround has been provided.