This is Xamarin's bug tracking system. For product support, please use the support links listed in your Xamarin Account.
Bug 262 - Stop sockets-io.c from blocking unknown address families
Summary: Stop sockets-io.c from blocking unknown address families
Status: CONFIRMED
Alias: None
Product: Class Libraries
Classification: Mono
Component: System (show other bugs)
Version: unspecified
Hardware: PC Linux
: --- normal
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2011-08-11 07:27 UTC by Andy Hume
Modified: 2017-07-11 16:36 UTC (History)
5 users (show)

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


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

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

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.



_Notes_
[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.

Note You need to log in before you can comment on or make changes to this bug.