Esempio n. 1
0
        public bool Connect(string hostName, Int32 port)
        {
            Close();

            try
            {
                _Socket          = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                _Socket.Blocking = true;
                _Socket.Connect(hostName, port);
                if (_Socket.Connected)
                {
                    _LocalIP    = ((IPEndPoint)_Socket.LocalEndPoint).Address.ToString();
                    _LocalPort  = ((IPEndPoint)_Socket.LocalEndPoint).Port;
                    _RemoteIP   = ((IPEndPoint)_Socket.RemoteEndPoint).Address.ToString();
                    _RemotePort = ((IPEndPoint)_Socket.RemoteEndPoint).Port;
                    _Stream     = new NetworkStream(_Socket);
                }
                return(_Socket.Connected);
            }
            catch (SocketException sex)
            {
                RMLog.Exception(sex, "SocketException in TcpConnection::Connect().  ErrorCode=" + sex.ErrorCode.ToString());
                return(false);
            }
            catch (Exception ex)
            {
                RMLog.Exception(ex, "Exception in TcpConnection::Connect()");
                return(false);
            }
        }
Esempio n. 2
0
 public void ReceiveData(int milliseconds)
 {
     try
     {
         if ((Connected) && (_Socket.Poll(milliseconds * 1000, SelectMode.SelectRead)))
         {
             byte[] Buffer    = new byte[READ_BUFFER_SIZE];
             int    BytesRead = _Stream.Read(Buffer, 0, READ_BUFFER_SIZE);
             if (BytesRead == 0)
             {
                 // No bytes read means we have a disconnect
                 _Stream.Close();
                 _Socket.Close();
             }
             else
             {
                 // If we have bytes, add them to the buffer
                 NegotiateInbound(Buffer, BytesRead);
             }
         }
     }
     catch (SocketException sex)
     {
         RMLog.Exception(sex, "SocketException in TcpConnection::ReceiveData().  ErrorCode=" + sex.ErrorCode.ToString());
     }
     catch (Exception ex)
     {
         RMLog.Exception(ex, "Exception in TcpConnection::ReceiveData()");
     }
 }
Esempio n. 3
0
        public bool Listen(string ipAddress, Int32 port)
        {
            Close();

            try
            {
                IPAddress IPA = ParseIPAddress(ipAddress);
                _Socket = new Socket(IPA.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                if (!ProcessUtils.IsRunningOnMono && !OSUtils.IsWinXPOr2003) // From: https://github.com/statianzo/Fleck/blob/master/src/Fleck/WebSocketServer.cs
                {
#if __MonoCS__
#else
                    // Windows default to IPv6Only=true, so we call this to allow connections to both IPv4 and IPv6
                    // Mono will throw an exception, but that's OK because it defaults to allowing both IPv4 and IPv6
                    _Socket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)27, false); // 27 = SocketOptionName.IPv6Only
#endif
                }
                _Socket.Blocking = true;
                _Socket.Bind(new IPEndPoint(IPA, port));
                _Socket.Listen(5);

                return(true);
            }
            catch (SocketException sex)
            {
                RMLog.Exception(sex, "SocketException in TcpConnection::Listen().  ErrorCode=" + sex.ErrorCode.ToString());
                return(false);
            }
            catch (Exception ex)
            {
                RMLog.Exception(ex, "Exception in TcpConnection::Listen()");
                return(false);
            }
        }
Esempio n. 4
0
        public void Close()
        {
            if (Connected)
            {
                try
                {
                    if (ShutdownOnClose)
                    {
                        _Socket.Shutdown(SocketShutdown.Both);
                    }
                }
                catch (SocketException sex)
                {
                    RMLog.Exception(sex, "SocketException in TcpConnection::Close().  ErrorCode=" + sex.ErrorCode.ToString());
                }
                catch (Exception ex)
                {
                    RMLog.Exception(ex, "Exception in TcpConnection::Close()");
                }
                if (Connected)
                {
                    _Stream.Close();
                    _Socket.Close();
                }
            }

            InitSocket();
        }
Esempio n. 5
0
        public void Close()
        {
            if (Connected)
            {
                try
                {
                    if (ShutdownOnClose)
                    {
                        _Socket.Shutdown(SocketShutdown.Both);
                    }
                }
                catch (SocketException sex)
                {
                    switch (sex.ErrorCode)
                    {
                    case 10057: break;     // The socket is not connected

                    default: RMLog.Exception(sex, "SocketException in TcpConnection::Close().  ErrorCode=" + sex.ErrorCode.ToString()); break;
                    }
                }
                catch (Exception ex)
                {
                    RMLog.Exception(ex, "Exception in TcpConnection::Close()");
                }
                if (Connected)
                {
                    _Stream.Close();
                    _Socket.Close();
                }
            }

            InitSocket();
        }
Esempio n. 6
0
        public bool Listen(string ipAddress, Int32 port)
        {
            Close();

            try
            {
                IPEndPoint LocalEP;
                if ((string.IsNullOrEmpty(ipAddress)) || (ipAddress == "0.0.0.0"))
                {
                    LocalEP = new IPEndPoint(IPAddress.Any, port);
                }
                else
                {
                    LocalEP = new IPEndPoint(IPAddress.Parse(ipAddress), port);
                }

                _Socket          = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                _Socket.Blocking = true;
                _Socket.Bind(LocalEP);
                _Socket.Listen(5);

                return(true);
            }
            catch (SocketException sex)
            {
                RMLog.Exception(sex, "SocketException in TcpConnection::Listen().  ErrorCode=" + sex.ErrorCode.ToString());
                return(false);
            }
            catch (Exception ex)
            {
                RMLog.Exception(ex, "Exception in TcpConnection::Listen()");
                return(false);
            }
        }
Esempio n. 7
0
        public bool Open(byte[] socketInformationBytes)
        {
            try
            {
                SocketInformation SI = new SocketInformation();
                SI.ProtocolInformation = socketInformationBytes;
                SI.Options             = new SocketInformationOptions();
                SI.Options             = SocketInformationOptions.Connected;

                _Socket          = new Socket(SI);
                _Socket.Blocking = true;
                if (_Socket.Connected)
                {
                    _Stream = new NetworkStream(_Socket);
                }
                return(_Socket.Connected);
            }
            catch (SocketException sex)
            {
                RMLog.Exception(sex, "SocketException in TcpConnection::Open().  ErrorCode=" + sex.ErrorCode.ToString());
                return(false);
            }
            catch (Exception ex)
            {
                RMLog.Exception(ex, "Exception in TcpConnection::Open()");
                return(false);
            }
        }
Esempio n. 8
0
        public virtual bool Open(Socket socket)
        {
            Close();

            try
            {
                _Socket          = socket;
                _Socket.Blocking = true;
                if (_Socket.Connected)
                {
                    _LocalIP    = ((IPEndPoint)_Socket.LocalEndPoint).Address.ToString();
                    _LocalPort  = ((IPEndPoint)_Socket.LocalEndPoint).Port;
                    _RemoteIP   = ((IPEndPoint)_Socket.RemoteEndPoint).Address.ToString();
                    _RemotePort = ((IPEndPoint)_Socket.RemoteEndPoint).Port;
                    _Stream     = new NetworkStream(_Socket);
                }
                return(_Socket.Connected);
            }
            catch (SocketException sex)
            {
                RMLog.Exception(sex, "SocketException in TcpConnection::Open().  ErrorCode=" + sex.ErrorCode.ToString());
                return(false);
            }
            catch (Exception ex)
            {
                RMLog.Exception(ex, "Exception in TcpConnection::Open()");
                return(false);
            }
        }
Esempio n. 9
0
        public static string GetLocalIPs()
        {
            try
            {
                StringBuilder Result = new StringBuilder();

                IPAddress[] Addresses = Dns.GetHostAddresses(Dns.GetHostName());
                foreach (IPAddress Address in Addresses)
                {
                    if (Result.Length > 0)
                    {
                        Result.Append(",");
                    }
                    Result.Append(Address.ToString());
                }
                return(Result.ToString());
            }
            catch (SocketException sex)
            {
                RMLog.Exception(sex, "SocketException in TcpConnection::GetLocalIPs().  ErrorCode=" + sex.ErrorCode.ToString());
                return("");
            }
            catch (Exception ex)
            {
                RMLog.Exception(ex, "Exception in TcpConnection::GetLocalIPs()");
                return("");
            }
        }
Esempio n. 10
0
 public static string GetIPByName(string hostName)
 {
     try
     {
         return(Dns.GetHostEntry(hostName).AddressList[0].ToString());
     }
     catch (SocketException sex)
     {
         RMLog.Exception(sex, "SocketException in TcpConnection::GetIPByName().  ErrorCode=" + sex.ErrorCode.ToString());
         return("");
     }
     catch (Exception ex)
     {
         RMLog.Exception(ex, "Exception in TcpConnection::GetIPByName()");
         return("");
     }
 }
Esempio n. 11
0
 public static string GetHostByIP(string ipAddress)
 {
     try
     {
         return(Dns.GetHostEntry(ipAddress).HostName.ToString());
     }
     catch (SocketException sex)
     {
         RMLog.Exception(sex, "SocketException in TcpConnection::GetHostByIP().  ErrorCode=" + sex.ErrorCode.ToString());
         return("");
     }
     catch (Exception ex)
     {
         RMLog.Exception(ex, "Exception in TcpConnection::GetHostByIP()");
         return("");
     }
 }
Esempio n. 12
0
 public bool CanAccept(int milliseconds)
 {
     try
     {
         return((_Socket == null) ? false : _Socket.Poll(milliseconds * 1000, SelectMode.SelectRead));
     }
     catch (SocketException sex)
     {
         RMLog.Exception(sex, "SocketException in TcpConnection::CanAccept().  ErrorCode=" + sex.ErrorCode.ToString());
         return(false);
     }
     catch (Exception ex)
     {
         RMLog.Exception(ex, "Exception in TcpConnection::CanAccept()");
         return(false);
     }
 }
Esempio n. 13
0
 public Socket Accept()
 {
     try
     {
         return(_Socket.Accept());
     }
     catch (SocketException sex)
     {
         RMLog.Exception(sex, "SocketException in TcpConnection::Accept().  ErrorCode=" + sex.ErrorCode.ToString());
         return(null);
     }
     catch (Exception ex)
     {
         RMLog.Exception(ex, "Exception in TcpConnection::Accept()");
         return(null);
     }
 }
Esempio n. 14
0
 public static IPAddress GetAddrByName(string hostName)
 {
     try
     {
         IPAddress[] Addresses = Dns.GetHostAddresses(hostName);
         return((Addresses.Length > 0) ? Addresses[0] : IPAddress.None);
     }
     catch (SocketException sex)
     {
         RMLog.Exception(sex, "SocketException in TcpConnection::GetAddrByName().  ErrorCode=" + sex.ErrorCode.ToString());
         return(IPAddress.None);
     }
     catch (Exception ex)
     {
         RMLog.Exception(ex, "Exception in TcpConnection::GetAddrByName()");
         return(IPAddress.None);
     }
 }
Esempio n. 15
0
 public void WriteRaw(byte[] data)
 {
     if (Connected)
     {
         try
         {
             // TODO Will this always write all the bytes?
             _Stream.Write(data, 0, data.Length);
         }
         catch (IOException ioex)
         {
             if (ioex.Message == "Write failure")
             {
                 // Apparently we have a disconnect
             }
             else
             {
                 RMLog.Exception(ioex, "IOException in TcpConnection::WriteRaw()");
             }
             _Stream.Close();
             _Socket.Close();
         }
         catch (SocketException sex)
         {
             if ((sex.Message == "An established connection was aborted by the software in your host machine") ||
                 (sex.Message == "An existing connection was forcibly closed by the remote host"))
             {
                 // Apparently we have a disconnect
             }
             else
             {
                 RMLog.Exception(sex, "SocketException in TcpConnection::WriteRaw().  ErrorCode=" + sex.ErrorCode.ToString());
             }
             _Stream.Close();
             _Socket.Close();
         }
         catch (Exception ex)
         {
             RMLog.Exception(ex, "Exception in TcpConnection::ReceiveData()");
             _Stream.Close();
             _Socket.Close();
         }
     }
 }
Esempio n. 16
0
 public TcpConnection AcceptTCP()
 {
     try
     {
         Socket        NewSocket     = _Socket.Accept();
         TcpConnection NewConnection = new TcpConnection();
         NewConnection.Open(NewSocket);
         return(NewConnection);
     }
     catch (SocketException sex)
     {
         RMLog.Exception(sex, "SocketException in TcpConnection::AcceptTCP().  ErrorCode=" + sex.ErrorCode.ToString());
         return(null);
     }
     catch (Exception ex)
     {
         RMLog.Exception(ex, "Exception in TcpConnection::AcceptTCP()");
         return(null);
     }
 }
Esempio n. 17
0
        public virtual bool Open(Socket socket)
        {
            Close();

            try
            {
                _Socket          = socket;
                _Socket.Blocking = true;
                if (_Socket.Connected)
                {
                    _LocalIP    = ((IPEndPoint)_Socket.LocalEndPoint).Address.ToString();
                    _LocalPort  = ((IPEndPoint)_Socket.LocalEndPoint).Port;
                    _RemoteIP   = ((IPEndPoint)_Socket.RemoteEndPoint).Address.ToString();
                    _RemotePort = ((IPEndPoint)_Socket.RemoteEndPoint).Port;
                    _Stream     = new NetworkStream(_Socket);

                    if (_RemoteIP.ToLower().StartsWith("::ffff:"))
                    {
                        _RemoteIP = _RemoteIP.Substring(7); // Trim leading ::ffff:
                    }
                    else if (((IPEndPoint)_Socket.RemoteEndPoint).Address.AddressFamily == AddressFamily.InterNetworkV6)
                    {
                        _RemoteIP = "[" + _RemoteIP + "]"; // Wrap IPv6 in []
                    }
                }
                return(_Socket.Connected);
            }
            catch (SocketException sex)
            {
                RMLog.Exception(sex, "SocketException in TcpConnection::Open().  ErrorCode=" + sex.ErrorCode.ToString());
                return(false);
            }
            catch (Exception ex)
            {
                RMLog.Exception(ex, "Exception in TcpConnection::Open()");
                return(false);
            }
        }
Esempio n. 18
0
        public bool Connect(string hostName, Int32 port)
        {
            Close();

            try
            {
                // Get the ip addresses for the give hostname, and then convert from ipv4 to ipv6 if necessary
                var HostAddresses = new List <IPAddress>();
                if (OSUtils.IsWinXPOr2003)
                {
                    HostAddresses.AddRange(Dns.GetHostAddresses(hostName));
                    _Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                }
                else
                {
                    foreach (var IPA in Dns.GetHostAddresses(hostName))
                    {
                        if (IPA.AddressFamily == AddressFamily.InterNetwork)
                        {
                            HostAddresses.Add(IPAddress.Parse("::ffff:" + IPA.ToString()));
                        }
                        else
                        {
                            HostAddresses.Add(IPA);
                        }
                    }

                    _Socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
                    // Only do the Mono check here because the XP check is done above
                    if (!ProcessUtils.IsRunningOnMono) // From: https://github.com/statianzo/Fleck/blob/master/src/Fleck/WebSocketServer.cs
                    {
#if __MonoCS__
#else
                        // Windows default to IPv6Only=true, so we call this to allow connections to both IPv4 and IPv6
                        // Mono will throw an exception, but that's OK because it defaults to allowing both IPv4 and IPv6
                        _Socket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)27, false); // 27 = SocketOptionName.IPv6Only
#endif
                    }
                }

                _Socket.Blocking = true;
                _Socket.Connect(HostAddresses.ToArray(), port);
                if (_Socket.Connected)
                {
                    _LocalIP    = ((IPEndPoint)_Socket.LocalEndPoint).Address.ToString();
                    _LocalPort  = ((IPEndPoint)_Socket.LocalEndPoint).Port;
                    _RemoteIP   = ((IPEndPoint)_Socket.RemoteEndPoint).Address.ToString();
                    _RemotePort = ((IPEndPoint)_Socket.RemoteEndPoint).Port;
                    _Stream     = new NetworkStream(_Socket);

                    if (_RemoteIP.ToLower().StartsWith("::ffff:"))
                    {
                        _RemoteIP = _RemoteIP.Substring(7); // Trim leading ::ffff:
                    }
                    else if (((IPEndPoint)_Socket.RemoteEndPoint).Address.AddressFamily == AddressFamily.InterNetworkV6)
                    {
                        _RemoteIP = "[" + _RemoteIP + "]"; // Wrap IPv6 in []
                    }
                }
                return(_Socket.Connected);
            }
            catch (SocketException sex)
            {
                switch (sex.ErrorCode)
                {
                case 10060: break;     // Connection timed out

                case 10061: break;     // Connection refused

                case 10065: break;     // No route to host

                default: RMLog.Exception(sex, "SocketException in TcpConnection::Connect().  ErrorCode=" + sex.ErrorCode.ToString()); break;
                }
                return(false);
            }
            catch (Exception ex)
            {
                RMLog.Exception(ex, "Exception in TcpConnection::Connect()");
                return(false);
            }
        }
Esempio n. 19
0
        private bool ShakeHands()
        {
            _Header["Version"] = "0";

            try
            {
                // Peek first byte for 22, 128 (indicates ssl)
                // Don't use class methods for peek/read since they eat data into the input buffer, and AuthenticateAsServer needs that data
                if (_Socket.Poll(5 * 1000 * 1000, SelectMode.SelectRead))
                {
                    byte[] FirstByte = new byte[1];
                    _Socket.Receive(FirstByte, 0, 1, SocketFlags.Peek);
                    if ((FirstByte[0] == 22) || (FirstByte[0] == 128))
                    {
                        if (_Certificate == null)
                        {
                            throw new Exception("wss:// requires a certificate");
                        }
                        else
                        {
                            var SSL = new SslStream(_Stream, false);
                            _Stream = SSL;
                            SSL.AuthenticateAsServer(_Certificate, false, SslProtocols.Tls, false);
                            Protocol = "wss";
                        }
                    }
                }
                else
                {
                    RMLog.Error("Timeout exceeded while waiting for complete handshake");
                    return(false);
                }

                // Keep reading header data until we get all the data we want
                while (true)
                {
                    // Read another line, and abort if we don't get one within 5 seconds
                    string InLine = ReadLn(new string[] { "\r\n", "\0" }, false, '\0', 5000).Trim();
                    if (ReadTimedOut)
                    {
                        RMLog.Error("Timeout exceeded while waiting for complete handshake");
                        return(false);
                    }

                    RMLog.Trace("Handshake Line: " + InLine);

                    // Check for blank line (indicates we have most of the header, and only the last 8 bytes remain
                    if (string.IsNullOrEmpty(InLine))
                    {
                        switch (_Header["Version"])
                        {
                        case "0":
                            if (_Header.ContainsKey("Sec-WebSocket-Key1"))
                            {
                                _ProtocolVersion = ProtocolVersion.Hixie76;
                                return(ShakeHandsHixie76());
                            }
                            else
                            {
                                // Only used by Chrome 4 and iOS 5.0.0 so probably not worth bothering
                                _ProtocolVersion = ProtocolVersion.Hixie75;
                                return(false);
                            }

                        case "7":
                        case "8":
                        case "13":
                            _ProtocolVersion = ProtocolVersion.RFC6455;
                            return(ShakeHandsRFC6455());

                        default:
                            //		    TODO If this version does not
                            //          match a version understood by the server, the server MUST
                            //          abort the websocket handshake described in this section and
                            //          instead send an appropriate HTTP error code (such as 426
                            //          Upgrade Required), and a |Sec-WebSocket-Version| header
                            //          indicating the version(s) the server is capable of
                            //          understanding.
                            return(false);
                        }
                        break;
                    }
                    else if (InLine.StartsWith("Connection:"))
                    {
                        // Example: "Connection: Upgrade"
                        // NB: New in protocol 8+
                        _Header["Connection"] = InLine.Replace("Connection:", "").Trim();
                    }
                    else if (InLine.StartsWith("GET"))
                    {
                        // Example: "GET /demo HTTP/1.1"
                        string[] GET = InLine.Split(' ');
                        _Header["Path"] = GET[1];
                    }
                    else if (InLine.StartsWith("Host:"))
                    {
                        // Example: "Host: example.com"
                        _Header["Host"] = InLine.Replace("Host:", "").Trim();
                    }
                    else if (InLine.StartsWith("Origin:"))
                    {
                        // Example: "Origin: http://example.com"
                        // NB: Not used in protocol 8+
                        _Header["Origin"] = InLine.Replace("Origin:", "").Trim();
                    }
                    else if (InLine.StartsWith("Sec-WebSocket-Key:"))
                    {
                        // Example: "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ=="
                        // NB: New in protocol 8+
                        _Header["Key"] = InLine.Replace("Sec-WebSocket-Key:", "").Trim();
                    }
                    else if (InLine.StartsWith("Sec-WebSocket-Key1:"))
                    {
                        // Example: "Sec-WebSocket-Key1: 4 @1  46546xW%0l 1 5"
                        // NB: Not used in protocol 8+
                        _Header["Key1"] = InLine.Replace("Sec-WebSocket-Key1:", "").Trim();
                    }
                    else if (InLine.StartsWith("Sec-WebSocket-Key2:"))
                    {
                        // Example: "Sec-WebSocket-Key2: 12998 5 Y3 1  .P00"
                        // NB: Not used in protocol 8+
                        _Header["Key2"] = InLine.Replace("Sec-WebSocket-Key2:", "").Trim();
                    }
                    else if (InLine.StartsWith("Sec-WebSocket-Origin:"))
                    {
                        // Example: "Sec-WebSocket-Origin: http://example.com"
                        // NB: New in protocol 8+
                        _Header["Origin"] = InLine.Replace("Sec-WebSocket-Origin:", "").Trim();
                    }
                    else if (InLine.StartsWith("Sec-WebSocket-Protocol:"))
                    {
                        // Example: "Sec-WebSocket-Protocol: sample"
                        _Header["SubProtocol"] = InLine.Replace("Sec-WebSocket-Protocol:", "").Trim();
                    }
                    else if (InLine.StartsWith("Sec-WebSocket-Draft"))
                    {
                        // Example: "Sec-WebSocket-Draft: 2"
                        _Header["Version"] = InLine.Replace("Sec-WebSocket-Draft:", "").Trim();
                    }
                    else if (InLine.StartsWith("Sec-WebSocket-Version"))
                    {
                        // Example: "Sec-WebSocket-Version: 8"
                        _Header["Version"] = InLine.Replace("Sec-WebSocket-Version:", "").Trim();
                    }
                    else if (InLine.StartsWith("Upgrade:"))
                    {
                        // Example: "Upgrade: websocket"
                        // NB: New in protocol 8+
                        _Header["Upgrade"] = InLine.Replace("Upgrade:", "").Trim();
                    }
                    else if (InLine.StartsWith("<policy-file-request"))
                    {
                        string PolicyResponse =
                            "<?xml version=\"1.0\"?>\n" +
                            "<cross-domain-policy>\n" +
                            "   <allow-access-from domain=\"*\" to-ports=\"*\"/>\n" +
                            "   <site-control permitted-cross-domain-policies=\"all\"/>\n" +
                            "</cross-domain-policy>\n" +
                            "\0";
                        WriteRaw(Encoding.UTF8.GetBytes(PolicyResponse));
                        FlashPolicyFileRequest = true;
                        return(false);
                    }
                }
            }
            catch (Exception ex)
            {
                RMLog.Exception(ex, "Exception in WebSocketConnection::ShakeHands()");
            }

            return(false);
        }
Esempio n. 20
0
        public bool Open(int ASocketHandle)
        {
            if (OSUtils.IsWindows)
            {
                try
                {
                    NativeMethods.WSAData WSA    = new NativeMethods.WSAData();
                    SocketError           Result = NativeMethods.WSAStartup((short)0x0202, out WSA);
                    if (Result != SocketError.Success)
                    {
                        throw new SocketException(NativeMethods.WSAGetLastError());
                    }

                    SocketPermission SP = new SocketPermission(System.Security.Permissions.PermissionState.Unrestricted);
                    SP.Demand();

                    SocketInformation SI = new SocketInformation();
                    SI.Options             = SocketInformationOptions.Connected;
                    SI.ProtocolInformation = new byte[Marshal.SizeOf(typeof(NativeMethods.WSAPROTOCOL_INFO))];

                    Result = SocketError.Success;
                    unsafe
                    {
                        fixed(byte *pinnedBuffer = SI.ProtocolInformation)
                        {
                            Result = NativeMethods.WSADuplicateSocket(new IntPtr(ASocketHandle), (uint)Process.GetCurrentProcess().Id, pinnedBuffer);
                        }
                    }

                    if (Result != SocketError.Success)
                    {
                        throw new SocketException(NativeMethods.WSAGetLastError());
                    }

                    return(Open(new Socket(SI)));
                }
                catch (SocketException sex)
                {
                    RMLog.Exception(sex, "SocketException in TcpConnection::Open().  ErrorCode=" + sex.ErrorCode.ToString());
                    return(false);
                }
                catch (Exception ex)
                {
                    RMLog.Exception(ex, "Exception in TcpConnection::Open()");
                    return(false);
                }
            }
            else
            {
                try
                {
                    SocketInformation SI = new SocketInformation();
                    SI.Options             = SocketInformationOptions.Connected;
                    SI.ProtocolInformation = new byte[24];

                    // From Mono's Socket.cs DuplicateAndClose() SI.ProtocolInformation = Mono.DataConverter.Pack("iiiil", (int)address_family, (int)socket_type, (int)protocol_type, isbound ? 1 : 0, (long)socket);
                    byte[] B1 = BitConverter.GetBytes((int)AddressFamily.InterNetwork);
                    byte[] B2 = BitConverter.GetBytes((int)SocketType.Stream);
                    byte[] B3 = BitConverter.GetBytes((int)ProtocolType.Tcp);
                    byte[] B4 = BitConverter.GetBytes((int)1);
                    byte[] B5 = BitConverter.GetBytes((long)ASocketHandle);
                    Array.Copy(B1, 0, SI.ProtocolInformation, 0, B1.Length);
                    Array.Copy(B2, 0, SI.ProtocolInformation, 4, B2.Length);
                    Array.Copy(B3, 0, SI.ProtocolInformation, 8, B3.Length);
                    Array.Copy(B4, 0, SI.ProtocolInformation, 12, B4.Length);
                    Array.Copy(B5, 0, SI.ProtocolInformation, 16, B5.Length);

                    return(Open(new Socket(SI)));
                }
                catch (SocketException sex)
                {
                    RMLog.Exception(sex, "SocketException in TcpConnection::Open().  ErrorCode=" + sex.ErrorCode.ToString());
                    return(false);
                }
                catch (Exception ex)
                {
                    RMLog.Exception(ex, "Exception in TcpConnection::Open()");
                    return(false);
                }
            }
        }