Bug 262 - Stop sockets-io.c from blocking unknown address families
Summary: Stop sockets-io.c from blocking unknown address families
Alias: None
Product: Class Libraries
Classification: Mono
Component: System ()
Version: unspecified
Hardware: PC Linux
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
Depends on:
Reported: 2011-08-11 07:27 UTC by Andy Hume
Modified: 2017-07-11 16:36 UTC (History)
5 users (show)

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

Patch (1.80 KB, application/octet-stream)
2011-08-11 07:27 UTC, Andy Hume

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 for Bug 262 on GitHub or Developer Community if you have new information to add and do not yet see a matching new report.

If the latest results still closely match this report, you can use the original description:

  • Export the original title and description: GitHub Markdown or Developer Community HTML
  • Copy the title and description into the new report. Adjust them to be up-to-date if needed.
  • Add your new information.

In special cases on GitHub you might also want the comments: GitHub Markdown with public comments

Related Links:

Description Andy Hume 2011-08-11 07:27:17 UTC
Created attachment 109 [details]

Mono currently only allows access to a very restricted set of socket types, effectively TCP/IP, UDP and UNIX.  Various other socket types can be present on current systems however.  In particular I need to access Bluetooth sockets on Linux BlueZ.  This is currently not possible; if sockets-io.c does not have explicit support for an AddressFamily then usage is disallowed.  However all other support is in place.

To otherwise add support for Bluetooth on Linux one would need to P/Invoke to all the sockets functions which would be very difficult[1].  Various workarounds were then suggested to me by Mono people, but none could be successfully implemented[2].  When that failed I got another suggestion from mono-devel-list, which was to patch sockets-io.c to not disallow non-explicitly supported address families.

So I modified sockets-io.c so that it simply doesn't block the user from using Address Families and sockaddr structs which it does not explicitly support.  With these minor changes I can simply use Bluetooth sockets with "new Socket(AF_BLUETOOTH, SocketType.Stream, Rfcomm)".  Success.

I attach that patch.  I'd be very pleased if this could be considered for inclusion.

It makes four changes:
1. convert_family (convert managed AF -> native AF): Change one line so that if the AF is not explicitly supported, don't block it, but allow it to be used.
2. convert_to_mono_family (native AF -> managed AF) : Ditto.
3. create_sockaddr_from_object (SocketAddress->sockaddr): If the AF is not explicitly supported, don't block it, but just copy use the SocketAddress as is.
4. create_object_from_sockaddr (sockaddr->SocketAddress): If the AF is not explicitly supported, don't block it, but just use the sockaddr as is.  Uses sockaddr_storage type (in get_sockaddr_size).

No other changes were required.  With that, socket, bind, connect, getsockname, getpeername and the I/Os method all work.

[1] To otherwise add support for Bluetooth on Linux would need one to P/Invoke to all the socket functions e.g. socket, recv, send, connect, etc.  Whilst implementing some (socket and close) might be fairly simple, reimplementing all the I/O methods would be difficult, and very very difficult if the end-developer wanted to use a Socket or NetworkStream.  And all that facility exists in Mono already...

[2] The second workaround suggested to me by the Mono team was to P/Invoke to create the Bluetooth native socket, then create a managed TCP/IP Socket, and use Reflection to overwrite its handle with the handle from the call to socket.  I implemented this but unfortunately this does not work as the handles used in Mono are WAPI Handles, and after various suggestions and attempts we found that there is no way to convert the socket handle to a WAPI handle.
Comment 1 Miguel de Icaza [MSFT] 2011-08-12 17:15:04 UTC
Would you mind doing a pull request, so we can have others comment on the patch?
Comment 2 Andy Hume 2011-08-18 09:36:19 UTC
Will do.  Once I work out how to do that. :-,)
Comment 3 Rodrigo Kumpera 2012-10-29 19:51:33 UTC
Patch looks ok. My only concern here is where do we fail if an invalid AF is passed in.

Can you state that this change is under MIT/X11 so it can be included?
Comment 4 Rodrigo Kumpera 2014-01-12 01:06:48 UTC
Andy, can you release your patch under the MIT license so it can be merged?
Comment 5 Andy Hume 2014-01-12 06:55:20 UTC
Glad to. Is this sufficient?

This patch is released under the MIT/X11 license by Andy Hume <andyhume32@yahoo.co.uk>.
Comment 6 Andy Hume 2014-01-23 07:33:53 UTC
Hope my release sentence is ok. Let me know if not.
Comment 7 Miguel de Icaza [MSFT] 2015-09-23 15:53:08 UTC
I am surprised I did not catch this on the first review.

The problem with this is that the code in question handles a number of well-known managed values and returns the system defined version of that value (convert_to_mono_family).

The issue with allowing any values is that allowing any values assumes that an arbitrary managed value will happen to be the same one as the system value.   This will break in cases where the arbitrary value that you want in unmanaged world happens to be identical to one of the defined constants in the managed world.

I suspect that ideally what we want is a series of new entry points that allow the creation of the objects from a sockaddr that completely skip over the mapping of address families.
Comment 8 Brook 2016-03-07 22:06:32 UTC
While not directly applicable to this "bug", the original need for this change may or may not be met by using BlueZ 5 and DBus to establish a bluetooth socket rather than using interop.  I can provide a link to a blog post on how to do this using Mono 4.33 if requested, but I will refrain from posting it for now to avoid coming off as spammy.
Comment 9 Brook 2016-03-07 22:12:31 UTC
PS, Thanks for your work on this Andy, your patch helped me limp along on BlueZ 4 for the last year or so on my project before finally getting things up and going on BlueZ 5.
Comment 10 Rodrigo Kumpera 2017-07-11 16:36:10 UTC
Moving to BCL as it needs the manage sockets code to deal with other families.