Exemplo n.º 1
0
        public SimpleActionResult Connect(string RemoteHost, int RemotePort, bool Secure, string CertificateServerName = null)
#endif
        {
            if (SupportedChannelSerializationModes.HasFlag(ChannelSerializationMode.MessagePack))
            {
                DebugEx.Assert(MsgPack != null, "MessagePack serializer not provided");
            }

            //init results
            var result = new SimpleActionResult()
            {
                IsSuccessful = false,
                Message      = "",
            };

            //check state
            if (_State != ChannelStates.Closed && _State != ChannelStates.Initializing)
            {
                result.Message = "Connected or connection already in progress";
                return(result);
            }

            //inform
            DebugEx.TraceLog($"YPChannel ({Name}) connecting to {RemoteHost}:{RemotePort}");

            //reset state
            if (_State != ChannelStates.Initializing)
            {
                Reset();
            }

            //keep connection parameters
            this.Secure = Secure;
            this.CertificateServerName = CertificateServerName;
#if NETFX
            this.CustomCertificates = CustomCertificates;
#endif
            try
            {
                //connect socket
                var connTask = TaskEx.RunSafe(() => _sockConnection(RemoteHost, RemotePort));
                connTask.Wait();
                //if (!connTask.Wait(SockConnectionTimeout))
                //throw new Exception("Socket connection timeout");
                var res = connTask.Result;
                if (!res)
                {
                    throw new Exception(result.Message);
                }
            }
            catch (Exception ex)
            {
                if (ex.InnerException != null)
                {
                    ex = ex.InnerException;
                }

                try { Close("YPChannel (" + (Name) + ") : Sock connection attempt failed, " + ex.Message); } catch { }
#if NETFX
                try { _sock?.Close(); } catch { }
#endif
                try { _sock?.Dispose(); } catch { }
                return(result);
            }

            //start heartbeat
            Start();

            //hook for system close
            Channel.OnSystemShutDownRequest?.Add(Yodiwo.WeakAction <object> .Create(_OnSystemShutDownRequestHandler));

            //wait for negotiation finish
            while (State == ChannelStates.Initializing || State == ChannelStates.Negotiating)
            {
                Thread.Sleep(200);
            }

            //set message
            if (State != ChannelStates.Open)
            {
                result.Message = "Could not open channel (Negotiation Failed)";
            }

            //return state
            result.IsSuccessful = State == ChannelStates.Open;
            if (result.IsSuccessful && result.Message == "")
            {
                result.Message = "Connection Established (Channel Openned)";
            }

            return(result);
        }
Exemplo n.º 2
0
        public SimpleActionResult Connect(string RemoteHost, int RemotePort, bool Secure, string CertificateServerName = null)
#endif
        {
            if (SupportedChannelSerializationModes.HasFlag(ChannelSerializationMode.MessagePack))
            {
                DebugEx.Assert(MsgPack != null, "MessagePack serializer not provided");
            }

            //init results
            var result = new SimpleActionResult()
            {
                IsSuccessful = false,
                Message      = "",
            };

            //check state
            if (_State != ChannelStates.Closed && _State != ChannelStates.Initializing)
            {
                result.Message = "Connected or connection already in progress";
                return(result);
            }

            //reset state
            if (_State != ChannelStates.Initializing)
            {
                Reset();
            }

            //keep connection parameters
            this.Secure = Secure;
            this.CertificateServerName = CertificateServerName;
#if NETFX
            this.CustomCertificates = CustomCertificates;
#endif

            //connect socket
            var res = _sockConnection(RemoteHost, RemotePort);
            if (!res)
            {
                return(res);
            }

            //start heartbeat
            Start();

            //wait for negotiation finish
            while (State == ChannelStates.Initializing || State == ChannelStates.Negotiating)
            {
                Thread.Sleep(100);
            }

            //set message
            if (State != ChannelStates.Open)
            {
                result.Message = "Could not open channel (Negotiation Failed)";
            }

            //return state
            result.IsSuccessful = State == ChannelStates.Open;
            if (result.IsSuccessful && result.Message == "")
            {
                result.Message = "Connection Established (Channel Openned)";
            }

            //hook for system close
            Channel.OnSystemShutDownRequest.Add(Yodiwo.WeakAction <object> .Create(_OnSystemShutDownRequestHandler));

            return(result);
        }
Exemplo n.º 3
0
        public virtual bool SetupServerSocket()
#endif
        {
            try
            {
                //keep
                bool   isSecured   = false;
                string sslProtocol = "";

                //check packer
                if (SupportedChannelSerializationModes.HasFlag(ChannelSerializationMode.MessagePack))
                {
                    DebugEx.Assert(MsgPack != null, "MessagePack serializer not provided");
                }

                //create network stream
#if NETFX
                //Stream _netstream = new BufferedStream(new NetworkStream(base._sock, true));
                Stream _netstream = new NetworkStream(base._sock, true);

                //Wrap with a secure stream?
                if (Server.Certificate != null)
                {
                    var sslstream = new SslStream(_netstream, false);
                    try
                    {
                        //try authenticate
                        sslstream.AuthenticateAsServer(Server.Certificate, false, SslProtocols.Tls | SslProtocols.Tls12 | SslProtocols.Tls11, true);

                        //checks
                        if (!sslstream.IsAuthenticated)
                        {
                            DebugEx.Assert("Not authenticated");
                            throw new Exception("Not authenticated");
                        }
                        if (!sslstream.IsEncrypted)
                        {
                            DebugEx.Assert("No encryption");
                            throw new Exception("Not encryption");
                        }

                        //get info
                        isSecured   = true;
                        sslProtocol = sslstream.SslProtocol.ToStringInvariant();

                        //use this stream from now on
                        _netstream = sslstream;
                    }
                    catch (Exception ex)
                    {
                        var msg = ex.Message;
                        if (ex.InnerException != null && ex.InnerException.Message != ex.Message)
                        {
                            msg += "  (inner msg=" + ex.InnerException.Message + ")";
                        }
                        DebugEx.TraceError("Certificate not accepted, " + msg);
                        try { Close("Certificate not accepted, " + msg); } catch { }
                        try { sslstream.Close(); base._sock.Dispose(); } catch { }
                        try { _netstream.Close(); _netstream.Dispose(); } catch { }
                        try { _sock.Close(); _sock.Dispose(); } catch { }
                        return(false); //failed
                    }
                }
#endif

                //read clients packers
                var clientPackers          = ChannelSerializationMode.Unkown;
                var clientPreferredPackers = ChannelSerializationMode.Unkown;
#if NETFX
                clientPackers          = (ChannelSerializationMode)_netstream.ReadByte();
                clientPreferredPackers = (ChannelSerializationMode)_netstream.ReadByte();
#elif UNIVERSAL
                clientPackers          = (ChannelSerializationMode)_sock.InputStream.AsStreamForRead().ReadByte();
                clientPreferredPackers = (ChannelSerializationMode)_sock.InputStream.AsStreamForRead().ReadByte();
#endif

                //filter packers
                clientPackers          = clientPackers & SupportedChannelSerializationModes;
                clientPreferredPackers = clientPackers & clientPreferredPackers;
                var serverPreferredPackers = clientPackers & PreferredChannelSerializationModes;
                var commonPreferredPackers = clientPreferredPackers & serverPreferredPackers;

                //choose packer
                if ((_ChannelSerializationMode = _choosePacker(commonPreferredPackers)) == ChannelSerializationMode.Unkown &&
                    (_ChannelSerializationMode = _choosePacker(clientPreferredPackers)) == ChannelSerializationMode.Unkown &&
                    (_ChannelSerializationMode = _choosePacker(serverPreferredPackers)) == ChannelSerializationMode.Unkown &&
                    (_ChannelSerializationMode = _choosePacker(clientPackers)) == ChannelSerializationMode.Unkown)
                {
                    DebugEx.TraceError("Could not decide on packer.");
                    try { Close("Could not decide on packer."); } catch { }
#if NETFX
                    try { _netstream?.Close(); _netstream?.Dispose(); } catch { }
                    try { _sock?.Close(); _sock?.Dispose(); } catch { }
#elif UNIVERSAL
                    try { _sock?.Dispose(); } catch { }
#endif
                    return(false); //failed
                }

                //write packer
#if NETFX
                var _nodelay = _sock.NoDelay;
                _sock.NoDelay = true;     //Disable the Nagle Algorithm
                _netstream.WriteByte((byte)_ChannelSerializationMode);
                _sock.NoDelay = _nodelay; //Restore (default:enable) the Nagle Algorithm
#elif UNIVERSAL
                {
                    var wStream = _sock.OutputStream.AsStreamForWrite();
                    wStream.WriteByte((byte)_ChannelSerializationMode);
                    wStream.Flush();
                }
#endif

                //setup info
                try
                {
#if NETFX
                    this.LocalHost  = base._sock.LocalEndPoint.GetIPAddress().ToString();
                    this.RemotePort = _sock.LocalEndPoint.GetPort().ToStringInvariant();
#elif UNIVERSAL
                    this.LocalHost  = _sock.Information.LocalAddress.ToString();
                    this.RemotePort = _sock.Information.LocalPort;
#endif
                }
                catch { }

                //setup info
#if NETFX
                this.RemoteHost = base._sock.RemoteEndPoint.GetIPAddress().ToString();
                this.RemotePort = _sock.RemoteEndPoint.GetPort().ToStringInvariant();
#elif UNIVERSAL
                this.LocalHost  = _sock.Information.RemoteAddress.ToString();
                this.RemotePort = _sock.Information.RemotePort;
#endif

                //log
                DebugEx.TraceLog("YPServer (socks) new connection from " + RemoteHost + ":" + RemotePort + " (Secure=" + isSecured + ",SSL=" + sslProtocol + ")");

                //setup stream
#if NETFX
                SetupStream(_netstream);
#elif UNIVERSAL
                SetupStream();
#endif

                //all ok
                return(true);
            }
            catch (Exception ex)
            {
                DebugEx.TraceError(ex, "Unhandled exception caught");
                return(false);
            }
        }