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); }
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); }
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); } }