const string TIMEOUT_EXCEPTION_MSG = "A connection attempt failed because the connected party did not properly respond" +
"after a period of time, or established connection failed because connected host has failed to respond";
- /*
- * These two fields are looked up by name by the runtime, don't change
- * their name without also updating the runtime code.
- */
- static int ipv4_supported = -1;
- static int ipv6_supported = -1;
-
/* true if we called Close_internal */
bool is_closed;
int m_IntCleanedUp;
internal bool connect_in_progress;
- private static volatile bool s_LoggingEnabled = Logging.On;
-
#region Constructors
- static Socket ()
- {
- if (ipv4_supported == -1) {
- try {
- Socket tmp = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- tmp.Close();
-
- ipv4_supported = 1;
- } catch {
- ipv4_supported = 0;
- }
- }
-
- if (ipv6_supported == -1) {
- // We need to put a try/catch around ConfigurationManager methods as will always throw an exception
- // when run in a mono embedded application. This occurs as embedded applications do not have a setup
- // for application config. The exception is not thrown when called from a normal .NET application.
- //
- // We, then, need to guard calls to the ConfigurationManager. If the config is not found or throws an
- // exception, will fall through to the existing Socket / API directly below in the code.
- //
- // Also note that catching ConfigurationErrorsException specifically would require library dependency
- // System.Configuration, and wanted to avoid that.
-#if !MOBILE
-#if CONFIGURATION_DEP
- try {
- SettingsSection config;
- config = (SettingsSection) System.Configuration.ConfigurationManager.GetSection ("system.net/settings");
- if (config != null)
- ipv6_supported = config.Ipv6.Enabled ? -1 : 0;
- } catch {
- ipv6_supported = -1;
- }
-#else
- try {
- NetConfig config = System.Configuration.ConfigurationSettings.GetConfig("system.net/settings") as NetConfig;
- if (config != null)
- ipv6_supported = config.ipv6Enabled ? -1 : 0;
- } catch {
- ipv6_supported = -1;
- }
-#endif
-#endif
- if (ipv6_supported != 0) {
- try {
- Socket tmp = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
- tmp.Close();
-
- ipv6_supported = 1;
- } catch {
- ipv6_supported = 0;
- }
- }
- }
- }
-
- public Socket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType)
- {
- this.addressFamily = addressFamily;
- this.socketType = socketType;
- this.protocolType = protocolType;
-
- int error;
- this.m_Handle = new SafeSocketHandle (Socket_internal (addressFamily, socketType, protocolType, out error), true);
-
- if (error != 0)
- throw new SocketException (error);
-
- SocketDefaults ();
- }
public Socket (SocketInformation socketInformation)
{
this.is_bound = (ProtocolType) (int) result [3] != 0;
this.m_Handle = new SafeSocketHandle ((IntPtr) (long) result [4], true);
+ InitializeSockets ();
+
SocketDefaults ();
}
this.m_Handle = safe_handle;
this.is_connected = true;
+
+ InitializeSockets ();
}
void SocketDefaults ()
#region Properties
- [ObsoleteAttribute ("Use OSSupportsIPv4 instead")]
- public static bool SupportsIPv4 {
- get { return ipv4_supported == 1; }
- }
-
- [ObsoleteAttribute ("Use OSSupportsIPv6 instead")]
- public static bool SupportsIPv6 {
- get { return ipv6_supported == 1; }
- }
-
-#if MOBILE
- public static bool OSSupportsIPv4 {
- get { return ipv4_supported == 1; }
- }
-#else
- public static bool OSSupportsIPv4 {
- get {
- NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces ();
-
- foreach (NetworkInterface adapter in nics) {
- if (adapter.Supports (NetworkInterfaceComponent.IPv4))
- return true;
- }
-
- return false;
- }
- }
-#endif
-
-#if MOBILE
- public static bool OSSupportsIPv6 {
- get { return ipv6_supported == 1; }
- }
-#else
- public static bool OSSupportsIPv6 {
- get {
- NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces ();
-
- foreach (NetworkInterface adapter in nics) {
- if (adapter.Supports (NetworkInterfaceComponent.IPv6))
- return true;
- }
-
- return false;
- }
- }
-#endif
-
public int Available {
get {
ThrowIfDisposedAndClosed ();
Connect (Dns.GetHostAddresses (host), port);
}
- public void Connect (IPAddress[] addresses, int port)
- {
- ThrowIfDisposedAndClosed ();
-
- if (addresses == null)
- throw new ArgumentNullException ("addresses");
- if (this.AddressFamily != AddressFamily.InterNetwork && this.AddressFamily != AddressFamily.InterNetworkV6)
- throw new NotSupportedException ("This method is only valid for addresses in the InterNetwork or InterNetworkV6 families");
- if (is_listening)
- throw new InvalidOperationException ();
-
- // FIXME: do non-blocking sockets Poll here?
- int error = 0;
- foreach (IPAddress address in addresses) {
- IPEndPoint iep = new IPEndPoint (address, port);
-
- iep = RemapIPEndPoint (iep);
-
- Connect_internal (m_Handle, iep.Serialize (), out error, is_blocking);
- if (error == 0) {
- is_connected = true;
- is_bound = true;
- seed_endpoint = iep;
- return;
- }
- if (error != (int)SocketError.InProgress && error != (int)SocketError.WouldBlock)
- continue;
-
- if (!is_blocking) {
- Poll (-1, SelectMode.SelectWrite);
- error = (int)GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error);
- if (error == 0) {
- is_connected = true;
- is_bound = true;
- seed_endpoint = iep;
- return;
- }
- }
- }
-
- if (error != 0)
- throw new SocketException (error);
- }
-
-
public void Connect (EndPoint remoteEP)
{
ThrowIfDisposedAndClosed ();
return true;
}
- public static bool ConnectAsync (SocketType socketType, ProtocolType protocolType, SocketAsyncEventArgs e)
- {
- var sock = new Socket (e.RemoteEndPoint.AddressFamily, socketType, protocolType);
- return sock.ConnectAsync (e);
- }
-
public static void CancelConnectAsync (SocketAsyncEventArgs e)
{
if (e == null)
if (endPoint == null)
throw new ArgumentNullException ("endPoint");
- SocketAsyncResult sockares = ValidateEndIAsyncResult (asyncResult, "EndReceiveMessageFrom", "asyncResult");
+ /*SocketAsyncResult sockares =*/ ValidateEndIAsyncResult (asyncResult, "EndReceiveMessageFrom", "asyncResult");
throw new NotImplementedException ();
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool SupportsPortReuse (ProtocolType proto);
+
+ internal static int FamilyHint {
+ get {
+ // Returns one of
+ // MONO_HINT_UNSPECIFIED = 0,
+ // MONO_HINT_IPV4 = 1,
+ // MONO_HINT_IPV6 = 2,
+
+ int hint = 0;
+ if (OSSupportsIPv4) {
+ hint = 1;
+ }
+
+ if (OSSupportsIPv6) {
+ hint = hint == 0 ? 2 : 0;
+ }
+
+ return hint;
+ }
+ }
+
+ static bool IsProtocolSupported (NetworkInterfaceComponent networkInterface)
+ {
+#if MOBILE
+ return true;
+#else
+ var nics = NetworkInterface.GetAllNetworkInterfaces ();
+ foreach (var adapter in nics) {
+ if (adapter.Supports (networkInterface))
+ return true;
+ }
+
+ return false;
+#endif
+ }
}
}