コード例 #1
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.DebugException(sex, "SocketException in TcpConnection::GetLocalIPs().  ErrorCode=" + sex.ErrorCode.ToString());
                return("");
            }
            catch (Exception ex)
            {
                RMLog.DebugException(ex, "Exception in TcpConnection::GetLocalIPs()");
                return("");
            }
        }
コード例 #2
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.DebugException(sex, "SocketException in TcpConnection::Close().  ErrorCode=" + sex.ErrorCode.ToString()); break;
                    }
                }
                catch (Exception ex)
                {
                    RMLog.DebugException(ex, "Exception in TcpConnection::Close()");
                }
                if (Connected)
                {
                    _Stream.Close();
                    _Socket.Close();
                }
            }

            InitSocket();
        }
コード例 #3
0
ファイル: TcpConnection.cs プロジェクト: Robin--/RMLib
 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()");
     }
 }
コード例 #4
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 && Socket.OSSupportsIPv6) // 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.DebugException(sex, "SocketException in TcpConnection::Listen().  ErrorCode=" + sex.ErrorCode.ToString());
                return(false);
            }
            catch (Exception ex)
            {
                RMLog.DebugException(ex, "Exception in TcpConnection::Listen()");
                return(false);
            }
        }
コード例 #5
0
        public bool Open(byte[] socketInformationBytes)
        {
            try
            {
                SocketInformation SI = new SocketInformation()
                {
                    ProtocolInformation = socketInformationBytes,
                    Options             = SocketInformationOptions.Connected,
                };

                _Socket = new Socket(SI)
                {
                    Blocking = true,
                };
                if (_Socket.Connected)
                {
                    _Stream = new NetworkStream(_Socket);
                }
                return(_Socket.Connected);
            }
            catch (SocketException sex)
            {
                RMLog.DebugException(sex, "SocketException in TcpConnection::Open().  ErrorCode=" + sex.ErrorCode.ToString());
                return(false);
            }
            catch (Exception ex)
            {
                RMLog.DebugException(ex, "Exception in TcpConnection::Open()");
                return(false);
            }
        }
コード例 #6
0
ファイル: TcpConnection.cs プロジェクト: Robin--/RMLib
        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);
            }
        }
コード例 #7
0
ファイル: TcpConnection.cs プロジェクト: Robin--/RMLib
        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);
            }
        }
コード例 #8
0
ファイル: TcpConnection.cs プロジェクト: Robin--/RMLib
        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);
            }
        }
コード例 #9
0
ファイル: TcpConnection.cs プロジェクト: Robin--/RMLib
        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();
        }
コード例 #10
0
        private bool ShakeHandsHixie76()
        {
            // Ensure we have all the data we need
            if ((_Header.ContainsKey("Key1")) && (_Header.ContainsKey("Key2")) && (_Header.ContainsKey("Host")) && (_Header.ContainsKey("Origin")) && (_Header.ContainsKey("Path")))
            {
                List <byte> ToHash = new List <byte>();
                byte[]      TempBytes;

                // Get the data to hash
                TempBytes = BitConverter.GetBytes(CalculateWebSocketKey(_Header["Key1"]));
                for (int i = 3; i >= 0; i--)
                {
                    ToHash.Add(TempBytes[i]);
                }
                TempBytes = BitConverter.GetBytes(CalculateWebSocketKey(_Header["Key2"]));
                for (int i = 3; i >= 0; i--)
                {
                    ToHash.Add(TempBytes[i]);
                }
                ToHash.AddRange(ReadBytes(8));

                // Hash the data
                byte[] Hashed = MD5.Create().ComputeHash(ToHash.ToArray());

                // Setup the handshake response
                string Response = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" +
                                  "Upgrade: WebSocket\r\n" +
                                  "Connection: Upgrade\r\n" +
                                  "Sec-WebSocket-Origin: " + _Header["Origin"] + "\r\n" +
                                  "Sec-WebSocket-Location: ws://" + _Header["Host"] + _Header["Path"] + "\r\n";
                if (_Header.ContainsKey("SubProtocol"))
                {
                    Response += "Sec-WebSocket-Protocol: plain\r\n";                                     // Only sub-protocol we support
                }
                Response += "\r\n";

                // Send the response and return
                WriteBytes(Encoding.ASCII.GetBytes(Response));
                WriteBytes(Hashed);

                return(true);
            }
            else
            {
                // We're missing some pice of data, log what we do have
                RMLog.Error("Missing some piece of handshake data.  Here's what we have:");
                foreach (DictionaryEntry DE in _Header)
                {
                    RMLog.Error(DE.Key + " => " + DE.Value);
                }
                return(false);
            }
        }
コード例 #11
0
 public static string GetIPByName(string hostName)
 {
     try
     {
         return(Dns.GetHostEntry(hostName).AddressList[0].ToString());
     }
     catch (SocketException sex)
     {
         RMLog.DebugException(sex, "SocketException in TcpConnection::GetIPByName().  ErrorCode=" + sex.ErrorCode.ToString());
         return("");
     }
     catch (Exception ex)
     {
         RMLog.DebugException(ex, "Exception in TcpConnection::GetIPByName()");
         return("");
     }
 }
コード例 #12
0
 public Socket Accept()
 {
     try
     {
         return(_Socket.Accept());
     }
     catch (SocketException sex)
     {
         RMLog.DebugException(sex, "SocketException in TcpConnection::Accept().  ErrorCode=" + sex.ErrorCode.ToString());
         return(null);
     }
     catch (Exception ex)
     {
         RMLog.DebugException(ex, "Exception in TcpConnection::Accept()");
         return(null);
     }
 }
コード例 #13
0
 public static string GetHostByIP(string ipAddress)
 {
     try
     {
         return(Dns.GetHostEntry(ipAddress).HostName.ToString());
     }
     catch (SocketException sex)
     {
         RMLog.DebugException(sex, "SocketException in TcpConnection::GetHostByIP().  ErrorCode=" + sex.ErrorCode.ToString());
         return("");
     }
     catch (Exception ex)
     {
         RMLog.DebugException(ex, "Exception in TcpConnection::GetHostByIP()");
         return("");
     }
 }
コード例 #14
0
 public bool CanAccept(int milliseconds)
 {
     try
     {
         return((_Socket == null) ? false : _Socket.Poll(milliseconds * 1000, SelectMode.SelectRead));
     }
     catch (SocketException sex)
     {
         RMLog.DebugException(sex, "SocketException in TcpConnection::CanAccept().  ErrorCode=" + sex.ErrorCode.ToString());
         return(false);
     }
     catch (Exception ex)
     {
         RMLog.DebugException(ex, "Exception in TcpConnection::CanAccept()");
         return(false);
     }
 }
コード例 #15
0
        private bool ShakeHandsRFC6455()
        {
            // Ensure we have all the data we need
            // TODOX Firefox (v49, maybe others) is not sending an Origin header, which breaks things
            // TODOX if ((_Header.ContainsKey("Key")) && (_Header.ContainsKey("Host")) && (_Header.ContainsKey("Origin")) && (_Header.ContainsKey("Path")))
            if ((_Header.ContainsKey("Key")) && (_Header.ContainsKey("Host")) && (_Header.ContainsKey("Path")))
            {
                string AcceptGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";

                // Combine Key and GUID
                string ToHash = _Header["Key"] + AcceptGUID;

                // Hash the string
                byte[] Hashed = SHA1.Create().ComputeHash(Encoding.ASCII.GetBytes(ToHash));

                // Encode the hash
                string Encoded = Convert.ToBase64String(Hashed);

                // Setup the handshake response
                var Response = "HTTP/1.1 101 Switching Protocols\r\n" +
                               "Upgrade: websocket\r\n" +
                               "Connection: Upgrade\r\n" +
                               "Sec-WebSocket-Accept: " + Encoded + "\r\n";
                if (_Header.ContainsKey("SubProtocol"))
                {
                    Response += "Sec-WebSocket-Protocol: plain\r\n";                                     // Only sub-protocol we support
                }
                Response += "\r\n";

                // Send the response and return
                WriteBytes(Encoding.ASCII.GetBytes(Response));

                return(true);
            }
            else
            {
                // We're missing some pice of data, log what we do have
                RMLog.Debug("Missing some piece of handshake data.  Here's what we have:");
                foreach (DictionaryEntry DE in _Header)
                {
                    RMLog.Debug(DE.Key + " => " + DE.Value);
                }
                return(false);
            }
        }
コード例 #16
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.DebugException(sex, "SocketException in TcpConnection::GetAddrByName().  ErrorCode=" + sex.ErrorCode.ToString());
         return(IPAddress.None);
     }
     catch (Exception ex)
     {
         RMLog.DebugException(ex, "Exception in TcpConnection::GetAddrByName()");
         return(IPAddress.None);
     }
 }
コード例 #17
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.DebugException(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.DebugException(sex, "SocketException in TcpConnection::WriteRaw().  ErrorCode=" + sex.ErrorCode.ToString());
             }
             _Stream.Close();
             _Socket.Close();
         }
         catch (Exception ex)
         {
             RMLog.DebugException(ex, "Exception in TcpConnection::ReceiveData()");
             _Stream.Close();
             _Socket.Close();
         }
     }
 }
コード例 #18
0
 public TcpConnection AcceptTCP()
 {
     try
     {
         Socket        NewSocket     = _Socket.Accept();
         TcpConnection NewConnection = new TcpConnection();
         NewConnection.Open(NewSocket);
         return(NewConnection);
     }
     catch (SocketException sex)
     {
         RMLog.DebugException(sex, "SocketException in TcpConnection::AcceptTCP().  ErrorCode=" + sex.ErrorCode.ToString());
         return(null);
     }
     catch (Exception ex)
     {
         RMLog.DebugException(ex, "Exception in TcpConnection::AcceptTCP()");
         return(null);
     }
 }
コード例 #19
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.DebugException(sex, "SocketException in TcpConnection::Open().  ErrorCode=" + sex.ErrorCode.ToString());
                return(false);
            }
            catch (Exception ex)
            {
                RMLog.DebugException(ex, "Exception in TcpConnection::Open()");
                return(false);
            }
        }
コード例 #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()
                    {
                        Options             = SocketInformationOptions.Connected,
                        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.DebugException(sex, "SocketException in TcpConnection::Open().  ErrorCode=" + sex.ErrorCode.ToString());
                    return(false);
                }
                catch (Exception ex)
                {
                    RMLog.DebugException(ex, "Exception in TcpConnection::Open()");
                    return(false);
                }
            }
            else
            {
                RMLog.Debug("MONO cannot open an existing socket handle");
                return(false);
                //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.DebugException(sex, "SocketException in TcpConnection::Open().  ErrorCode=" + sex.ErrorCode.ToString());
                //    return false;
                //}
                //catch (Exception ex)
                //{
                //    RMLog.DebugException(ex, "Exception in TcpConnection::Open()");
                //    return false;
                //}
            }
        }
コード例 #21
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);
        }
コード例 #22
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 (!Socket.OSSupportsIPv6)
                {
                    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.DebugException(sex, "SocketException in TcpConnection::Connect().  ErrorCode=" + sex.ErrorCode.ToString()); break;
                }
                return(false);
            }
            catch (Exception ex)
            {
                RMLog.DebugException(ex, "Exception in TcpConnection::Connect()");
                return(false);
            }
        }