[sockets] Correctly report that Linux supports double binding for UDP, even on old...
authorAlex Rønne Petersen <alexrp@xamarin.com>
Wed, 8 Jun 2016 13:27:47 +0000 (15:27 +0200)
committerAlex Rønne Petersen <alexrp@xamarin.com>
Wed, 8 Jun 2016 13:40:12 +0000 (15:40 +0200)
mcs/class/System/System.Net.Sockets/Socket.cs
mcs/class/corlib/System/Environment.cs
mono/metadata/appdomain.c
mono/metadata/socket-io.c
mono/metadata/socket-io.h

index 6715cdf22f84f6e39857589387914f2a6c1f2f8a..c7576897189c0e6c30b155b2380569a1867cc119 100644 (file)
@@ -3176,7 +3176,7 @@ namespace System.Net.Sockets
                {
                        ThrowIfDisposedAndClosed ();
 
-                       if (optionLevel == SocketOptionLevel.Socket && optionName == SocketOptionName.ReuseAddress && optionValue != 0 && !SupportsPortReuse ())
+                       if (optionLevel == SocketOptionLevel.Socket && optionName == SocketOptionName.ReuseAddress && optionValue != 0 && !SupportsPortReuse (protocol_type))
                                throw new SocketException ((int) SocketError.OperationNotSupported, "Operating system sockets do not support ReuseAddress.\nIf your socket is not intended to bind to the same address and port multiple times remove this option, otherwise you should ignore this exception inside a try catch and check that ReuseAddress is true before binding to the same address and port multiple times.");
 
                        int error;
@@ -3479,7 +3479,7 @@ namespace System.Net.Sockets
                internal static extern void cancel_blocking_socket_operation (Thread thread);
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               internal static extern bool SupportsPortReuse ();
+               internal static extern bool SupportsPortReuse (ProtocolType proto);
        }
 }
 
index fd5e734534ef56ad965b2fc8621ab86df4206507..dcfe35c85fc8899c4bf94d62686b272cfce0e50c 100644 (file)
@@ -57,7 +57,7 @@ namespace System {
                 * of icalls, do not require an increment.
                 */
 #pragma warning disable 169
-               private const int mono_corlib_version = 149;
+               private const int mono_corlib_version = 150;
 #pragma warning restore 169
 
                [ComVisible (true)]
index eb3f68204036d2f79ab525c3995a8a3a689867e4..3131dfafaa7c9b4bdece9a4e02fdec980ba05db9 100644 (file)
@@ -82,7 +82,7 @@
  * Changes which are already detected at runtime, like the addition
  * of icalls, do not require an increment.
  */
-#define MONO_CORLIB_VERSION 149
+#define MONO_CORLIB_VERSION 150
 
 typedef struct
 {
index ae1268c15222bb42c823274af45d475740a2dc0d..95bac2301bd8b5f9d0dc20e5adb70b777ebf1faf 100644 (file)
@@ -2832,12 +2832,17 @@ ves_icall_System_Net_Sockets_Socket_SendFile_internal (SOCKET sock, MonoString *
 }
 
 gboolean
-ves_icall_System_Net_Sockets_Socket_SupportPortReuse (void)
+ves_icall_System_Net_Sockets_Socket_SupportPortReuse (MonoProtocolType proto)
 {
 #if defined (SO_REUSEPORT) || defined (HOST_WIN32)
-    return TRUE;
+       return TRUE;
 #else
-    return FALSE;
+#ifdef __linux__
+       /* Linux always supports double binding for UDP, even on older kernels. */
+       if (proto == ProtocolType_Udp)
+               return TRUE;
+#endif
+       return FALSE;
 #endif
 }
 
index 138cc674d5b0f46410add6da353ae36c79a57deb..e228f0a2e63df038682a3d004622f541cf928284 100644 (file)
@@ -189,7 +189,7 @@ extern MonoBoolean ves_icall_System_Net_Sockets_Socket_Poll_internal (SOCKET soc
 extern void ves_icall_System_Net_Sockets_Socket_Disconnect_internal(SOCKET sock, MonoBoolean reuse, gint32 *error);
 extern gboolean ves_icall_System_Net_Sockets_Socket_SendFile_internal (SOCKET sock, MonoString *filename, MonoArray *pre_buffer, MonoArray *post_buffer, gint flags);
 void icall_cancel_blocking_socket_operation (MonoThread *thread);
-extern gboolean ves_icall_System_Net_Sockets_Socket_SupportPortReuse (void);
+extern gboolean ves_icall_System_Net_Sockets_Socket_SupportPortReuse (MonoProtocolType proto);
 
 extern void mono_network_init(void);
 extern void mono_network_cleanup(void);