/// <summary>
 /// Constructs an instance of the SecuritySession_ZpaServer class.
 /// </summary>
 /// <param name="name">Name of the SecuritySession being created.</param>
 /// <param name="remote">The remote host.</param>
 /// <param name="keyProvider_ZpaServer">The server key provider.</param>
 public SecuritySession_ZpaServer(string name, HostInformation remote, KeyProvider_ZpaServer keyProvider_ZpaServer)
     : base(name, remote, keyProvider_ZpaServer.ZpaFeatureFlags)
 {
     this.KeyProvider_ZpaServer = keyProvider_ZpaServer;
     Random random = new Random();
     this.Salt = ZeroProofAuthorizationUtility.GenerateArbitrarySequence(128 + random.Next(128));
 }
Exemple #2
0
        /// <summary>
        /// Constructs a fake instance of the HostInformation for debugging and diagnostic purposes.
        /// </summary>
        /// <returns>An instance of the HostInformation class filled with fake stuff.</returns>
        public static HostInformation ConstructInstanceForDebugging()
        {
            HostInformation hostInformation = new HostInformation("gtcp://fakehost:8737/fake.rem", null);

            hostInformation._uri = "gtcp://8089";
            hostInformation._remoteHostUniqueIdentifier = 15;
            return(hostInformation);
        }
        /// <summary>
        /// Constructs an instance of the SyncSocketWritingStream class.
        /// </summary>
        /// <param name="connectionManager">The Connection Manager.</param>
        /// <param name="socket">The socket.</param>
        /// <param name="writeTimeout">The timeout of the current operation.</param>
        /// <param name="dbgConnectionId">The identifier of the connection.</param>
        /// <param name="remote">Information about the remote host.</param>
        public SyncSocketWritingStream(ConnectionManager connectionManager, Socket socket, int writeTimeout, int dbgConnectionId, HostInformation remote)
        {
            this._connectionManager = connectionManager;
            this._socket = socket;
            this._writeTimeout = writeTimeout;

            this._dbgConnectionId = dbgConnectionId;
            this._remote = remote;
        }
Exemple #4
0
        /// <summary>
        /// Renews the host information.
        /// </summary>
        /// <param name="uriOrUrl">Uri or Url of the remote host.</param>
        /// <param name="timeSpan">The time period specified in milliseconds to renew host-related information.</param>
        /// <param name="canMakeShorter">Indicates whether this call may reduce the host expiration time.</param>
        public void Renew(string uriOrUrl, int timeSpan, bool canMakeShorter)
        {
            HostInformation hostInformation = null;

            hostInformation = this.Get(uriOrUrl);

            if (hostInformation != null)
            {
                hostInformation.Renew(timeSpan, canMakeShorter);
            }
        }
        /// <summary>
        /// Sends the content of the log to the remote host.
        /// </summary>
        /// <param name="stream">The stream containing a request or a response.</param>
        /// <param name="sender">The remote host that sent this request.</param>
        /// <returns>The response.</returns>
        public Stream HandleMessage(Stream stream, HostInformation sender)
        {
            if (_stopped)
                return Stream.Null;

            int expectedSize = 640000;

            // copy to an intermediate stream
            GenuineChunkedStream intermediateStream = new GenuineChunkedStream(true);
            GenuineUtility.CopyStreamToStream(this._memoryWritingStream, intermediateStream, expectedSize);

            // and send it as one chunk
            return intermediateStream;
        }
        /// <summary>
        /// Initializes an instance of the SecuritySession class.
        /// </summary>
        /// <param name="name">The name of the Security Session.</param>
        /// <param name="remote">Information about remote host.</param>
        public SecuritySession(string name, HostInformation remote)
        {
            this._name = name;
            this.Remote = remote;

            // LOG:
            BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter;
            if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0 )
                binaryLogWriter.WriteEvent(LogCategory.Security, "SecuritySession.SecuritySession",
                    LogMessageType.SecuritySessionCreated, null, null, remote, null,
                    GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, this,
                    name, -1,
                    0, 0, 0, this.GetType().Name, null, null, null,
                    "Security Session has been created.");
        }
 /// <summary>
 /// Constructs an instance of the SecuritySession_SelfEstablishingSymmetric class.
 /// </summary>
 /// <param name="name">Name of the SecuritySession being created.</param>
 /// <param name="remote">The remote host.</param>
 public SecuritySession_SelfEstablishingSymmetric(string name, HostInformation remote)
     : base(name, remote)
 {
     // to avoid an issue described in Q322371
     try
     {
         // try the usual way, and if fails, use the patch in the catch block
         this._rsaCryptoServiceProviderDecryptor = new RSACryptoServiceProvider();
     }
     catch
     {
         CspParameters _CSPParam = new CspParameters();
         _CSPParam.Flags = CspProviderFlags.UseMachineKeyStore;
         this._rsaCryptoServiceProviderDecryptor = new RSACryptoServiceProvider(_CSPParam);
     }
 }
Exemple #8
0
        /// <summary>
        /// Adds an element to the collection associated with the specified key.
        /// Ensures that there is the only instance of the element in the collection.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="hostInformation">The element being stored.</param>
        private void SetHostInformation(string key, HostInformation hostInformation)
        {
            lock (this.SyncRoot)
            {
                ArrayList arrayList = this._hashtable[key] as ArrayList;

                // if there is no collection corresponding to the key
                if (arrayList == null)
                {
                    arrayList            = new ArrayList();
                    this._hashtable[key] = arrayList;
                    arrayList.Add(hostInformation);
                    return;
                }

                // check whether this element is already in the collection
                for (int i = 0; i < arrayList.Count; i++)
                {
                    if (object.ReferenceEquals(arrayList[i], hostInformation))
                    {
                        return;
                    }

                    // TODO: What to do with this fix?! It does work, but only in really unusual circumstances.
                    // remove all HostInformations with empty URI, if the current hostInformation contains the URI
                    HostInformation currentHostInformation = (HostInformation)arrayList[i];
                    if (hostInformation.Url != null && currentHostInformation.Url == null &&
                        hostInformation.Uri == currentHostInformation.Uri && currentHostInformation.RemoteHostUniqueIdentifier == -1)
                    {
                        arrayList.RemoveAt(i);
                        arrayList.Add(hostInformation);
                        currentHostInformation.Dispose(GenuineExceptions.Get_Receive_ConflictOfConnections());
                        return;
                    }
                }

                arrayList.Add(hostInformation);
            }
        }
 /// <summary>
 /// Gets the name of the TCP connection.
 /// </summary>
 /// <param name="isServer">A boolean value indicating whether this connection manager works as a server.</param>
 /// <param name="hostInformation">The HostInformation of the remote host.</param>
 /// <param name="connectionName">The name of the connection.</param>
 /// <returns>The name of the TCP connection.</returns>
 private string GetNamedConnectionName(bool isServer, HostInformation hostInformation, string connectionName)
 {
     //			bool isServer = connectionName.StartsWith("~");
     return isServer ? hostInformation.Uri + "/" + connectionName : hostInformation.Url + "/" + connectionName;
 }
        /// <summary>
        /// Processes incoming requests and responses.
        /// </summary>
        /// <param name="stream">The stream containing a request or a response.</param>
        /// <param name="remote">The remote host.</param>
        /// <param name="genuineConnectionType">The type of the connection.</param>
        /// <param name="connectionName">Connection id to send a response through.</param>
        /// <param name="dbgConnectionId">The identifier of the connection, which is used for debugging purposes only.</param>
        /// <param name="useThisThread">True to invoke the target in the current thread.</param>
        /// <param name="iMessageRegistrator">The message registrator.</param>
        /// <param name="connectionLevelSecuritySession">Connection Level Security Session.</param>
        /// <param name="httpServerRequestResult">The HTTP request through which the message was received.</param>
        /// <returns>True if it's a one-way message.</returns>
        public bool HandleMessage(Stream stream, HostInformation remote, GenuineConnectionType genuineConnectionType, string connectionName, int dbgConnectionId, bool useThisThread, IMessageRegistrator iMessageRegistrator, SecuritySession connectionLevelSecuritySession, HttpServerRequestResult httpServerRequestResult)
        {
            // read the Security Session name
            BinaryReader binaryReader = new BinaryReader(stream);
            string sessionName = binaryReader.ReadString();
            Message message = null;
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;

            // and decode the packet
            SecuritySession securitySession = remote.GetSecuritySession(sessionName, this.ITransportContext.IKeyStore);
            if (securitySession == null)
            {
                // LOG:
                if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0 )
                {
                    binaryLogWriter.WriteEvent(LogCategory.Security, "GenuineReceivingHandler.HandleMessage",
                        LogMessageType.SecuritySessionApplied, GenuineExceptions.Get_Security_ContextNotFound(sessionName),
                        message, remote,
                        null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                        securitySession, sessionName, dbgConnectionId,
                        0, 0, 0, null, null, null, null,
                        "The requested Security Session can not be constructed or established. The name of Security Session: {0}.",
                        sessionName);
                }

                this.ITransportContext.IGenuineEventProvider.Fire(new GenuineEventArgs(GenuineEventType.SecuritySessionWasNotFound, GenuineExceptions.Get_Security_ContextNotFound(sessionName),
                    remote, null));

                return true;
            }

            // decode the stream and roll back if it was a Security Session's message
            stream = securitySession.Decrypt(stream);
            if (stream == null)
                return true;

            // read the message
            message = MessageCoder.Deserialize(stream, sessionName);
            message.ConnectionName = connectionName;
            message.SecuritySessionParameters._connectionName = connectionName;
            message.SecuritySessionParameters._genuineConnectionType = genuineConnectionType;
            message.Sender = remote;
            message.ITransportContext = this.ITransportContext;
            message.ConnectionLevelSecuritySession = connectionLevelSecuritySession;
            message.HttpServerRequestResult = httpServerRequestResult;

            // LOG:
            if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0 )
            {
                binaryLogWriter.WriteEvent(LogCategory.Security, "GenuineReceivingHandler.HandleMessage",
                    LogMessageType.SecuritySessionApplied, null, message, remote,
                    null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                    securitySession, sessionName, dbgConnectionId,
                    0, 0, 0, null, null, null, null,
                    "The Security Session has been used for decrypting the message.");
            }

            // LOG:
            if ( binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0 )
            {
                bool readContent = this.ITransportContext.BinaryLogWriter[LogCategory.MessageProcessing] > 1;
                if (readContent)
                {
                    GenuineChunkedStream streamClone = new GenuineChunkedStream();
                    GenuineUtility.CopyStreamToStream(message.Stream, streamClone);
                    message.Stream = streamClone;
                }

                binaryLogWriter.WriteMessageCreatedEvent("GenuineReceivingHandler.HandleMessage",
                    LogMessageType.MessageReceived, null, message, message.ReplyToId > 0, remote,
                    readContent ? message.Stream : null,
                    message.ITransportHeaders[Message.TransportHeadersInvocationTarget] as string, message.ITransportHeaders[Message.TransportHeadersMethodName] as string,
                    GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, connectionName, dbgConnectionId,
                    connectionLevelSecuritySession == null ? -1 : connectionLevelSecuritySession.SecuritySessionId,
                    connectionLevelSecuritySession == null ? null : connectionLevelSecuritySession.Name,
                    securitySession == null ? -1 : securitySession.SecuritySessionId,
                    securitySession.Name,
                    "The message has been received.");
            }

            if (message.ReplyToId == PING_MESSAGE_REPLYID)
                return true;

            if (iMessageRegistrator != null && iMessageRegistrator.WasRegistered(remote.Uri, message.MessageId, message.ReplyToId))
            {
                // LOG:
                if ( binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0 )
                    binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "GenuineReceivingHandler.HandleMessage",
                        LogMessageType.MessageDispatched, GenuineExceptions.Get_Debugging_GeneralWarning("The message has been already processed."), message, remote,
                        null,
                        GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, securitySession, securitySession.Name,
                        dbgConnectionId,
                        GenuineUtility.TickCount, 0, message.SeqNo, null, null, null, null,
                        "The message has been already processed. Therefore, this message is ignored.");

                return true;
            }

            // if it's a response, then direct the message to the response handler
            if (message.ReplyToId > 0)
            {
                message.IsOneWay = true;
                IResponseProcessor iResponseProcessor = GenuineReceivingHandler._responseHandlers[message.ReplyToId] as IResponseProcessor;

                // nothing waits for this request
                if (iResponseProcessor == null)
                    return true;

                // 2.5.1: set the answer flag
                if (iResponseProcessor.Message != null)
                    iResponseProcessor.Message.HasBeenAsnwered = true;

                if (iResponseProcessor.IsShortInProcessing)
                {
                    iResponseProcessor.ProcessRespose(message);

            #if TRIAL
            #else
                    if (iResponseProcessor.IsExpired(GenuineUtility.TickCount))
                        GenuineReceivingHandler._responseHandlers.Remove(message.ReplyToId);
            #endif

                    return true;
                }
            }

            // take care about the thread and call context
            if (useThisThread)
                InternalExecuteMessage(message);
            else
                GenuineThreadPool.QueueUserWorkItem(this._waitCallback_InternalExecuteMessagewaitCallback, message, false);

            return message.IsOneWay;
        }
 /// <summary>
 /// Creates SecuritySession which will perform all traffic processing in
 /// specific security context.
 /// </summary>
 /// <param name="name">Name of the SecuritySession being created.</param>
 /// <param name="remote">The remote host.</param>
 /// <returns>SecuritySession that will perform all traffic processing that is performed in specific security context.</returns>
 public SecuritySession CreateSecuritySession(string name, HostInformation remote)
 {
     return new SecuritySession_Basic(name);
 }
 /// <summary>
 /// Closes all connections that fit to the specified characteristics.
 /// Automatically releases all resources acquired by connections being closed.
 /// </summary>
 /// <param name="hostInformation">The host or a null reference to embrace all remote hosts.</param>
 /// <param name="genuineConnectionType">Specifies what connection patterns will be affected by this operation.</param>
 /// <param name="reason">The reason of resource releasing that will be dispatched to all callers waiting something from the connections being closed.</param>
 public abstract void ReleaseConnections(HostInformation hostInformation, GenuineConnectionType genuineConnectionType, Exception reason);
        /// <summary>
        /// Gets information about the remote host.
        /// Automatically creates and initializes a new instance of the HostInformation class when
        /// it is necessary.
        /// </summary>
        public HostInformation this[string uri]
        {
            get
            {
                lock (this.SyncRoot)
                {
                    HostInformation hostInformation = this.Get(uri);

                    if (hostInformation == null)
                    {
                        hostInformation = new HostInformation(uri, this.ITransportContext);
                        this.UpdateHost(uri, hostInformation);

                        // set a reasonable start up lifetime property value
                        int expiration = GenuineUtility.ConvertToMilliseconds(this.ITransportContext.IParameterProvider[GenuineParameter.ConnectTimeout]);
                        hostInformation.Renew(expiration, true);

                        // LOG:
                        BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter;
                        if ( binaryLogWriter != null && binaryLogWriter[LogCategory.HostInformation] > 0 )
                            binaryLogWriter.WriteEvent(LogCategory.HostInformation, "KnownHosts.this[string]",
                                LogMessageType.HostInformationCreated, null, null, hostInformation,
                                null,
                                GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                null, null, -1, 0, 0, 0, null, null, null, null,
                                "The HostInformation has been created for the remote host: {0}.", uri);
                    }
                    return hostInformation;
                }
            }
        }
        /// <summary>
        /// Adds an element to the collection associated with the specified key.
        /// Ensures that there is the only instance of the element in the collection.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="hostInformation">The element being stored.</param>
        private void SetHostInformation(string key, HostInformation hostInformation)
        {
            lock (this.SyncRoot)
            {
                ArrayList arrayList = this._hashtable[key] as ArrayList;

                // if there is no collection corresponding to the key
                if (arrayList == null)
                {
                    arrayList = new ArrayList();
                    this._hashtable[key] = arrayList;
                    arrayList.Add(hostInformation);
                    return ;
                }

                // check whether this element is already in the collection
                for ( int i = 0; i < arrayList.Count; i++ )
                {
                    if (object.ReferenceEquals(arrayList[i], hostInformation))
                        return ;

                    // TODO: What to do with this fix?! It does work, but only in really unusual circumstances.
                    // remove all HostInformations with empty URI, if the current hostInformation contains the URI
                    HostInformation currentHostInformation = (HostInformation) arrayList[i];
                    if (hostInformation.Url != null && currentHostInformation.Url == null &&
                        hostInformation.Uri == currentHostInformation.Uri && currentHostInformation.RemoteHostUniqueIdentifier == -1)
                    {
                        arrayList.RemoveAt(i);
                        arrayList.Add(hostInformation);
                        currentHostInformation.Dispose(GenuineExceptions.Get_Receive_ConflictOfConnections());
                        return ;
                    }
                }

                arrayList.Add(hostInformation);
            }
        }
 /// <summary>
 /// Updates a reference to the host.
 /// </summary>
 /// <param name="uriOrUrl">The reference.</param>
 /// <param name="hostInformation">The host.</param>
 internal void UpdateHost(string uriOrUrl, HostInformation hostInformation)
 {
     this.SetHostInformation(uriOrUrl, hostInformation);
 }
Exemple #16
0
 /// <summary>
 /// Constructs an instance of the HostInformationAndReason class.
 /// </summary>
 /// <param name="hostInformation">The remote host.</param>
 /// <param name="reason">The exception.</param>
 public HostInformationAndReason(HostInformation hostInformation, Exception reason)
 {
     this.HostInformation = hostInformation;
     this.Reason          = reason;
 }
Exemple #17
0
        /// <summary>
        /// Releases expired host structures.
        /// </summary>
        public void TimerCallback()
        {
            int             now             = GenuineUtility.TickCount;
            HostInformation hostInformation = null;

            // the released host
            ArrayList hostsToDelete = new ArrayList();

            // the entries being deleted
            ArrayList urisToDelete = new ArrayList();

            lock (this.SyncRoot)
            {
                // through all registered hosts
                foreach (DictionaryEntry entry in this._hashtable)
                {
                    ArrayList hosts = (ArrayList)entry.Value;
                    for (int i = 0; i < hosts.Count;)
                    {
                        hostInformation = (HostInformation)hosts[i];

                        // if the time has run out
                        if (GenuineUtility.IsTimeoutExpired(hostInformation.ExpireTime, now) || hostInformation.IsDisposed)
                        {
                            // exclude the host
                            hosts.RemoveAt(i);
                            hostsToDelete.Add(hostInformation);

                            // check on entry excluding
                            if (hosts.Count <= 0)
                            {
                                urisToDelete.Add(entry.Key);
                            }
                            continue;
                        }

                        i++;
                    }
                }

                // it is very important to remove all references to the host before disposing it
                foreach (string key in urisToDelete)
                {
                    this._hashtable.Remove(key);
                }

                // dispose all hosts
                foreach (HostInformation hostInformationExcluded in hostsToDelete)
                {
                    // LOG:
                    BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter;
                    if (binaryLogWriter != null && binaryLogWriter[LogCategory.HostInformation] > 0)
                    {
                        binaryLogWriter.WriteEvent(LogCategory.HostInformation, "KnownHosts.this[string]",
                                                   LogMessageType.HostInformationReferencesDisassociated, GenuineExceptions.Get_Debugging_GeneralWarning("The association between HostInformation and its URL or URI has been broken."),
                                                   null, hostInformationExcluded, null,
                                                   GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                   null, null, -1, 0, 0, 0, hostInformationExcluded.Uri, hostInformationExcluded.Url, null, null,
                                                   "The current HostInformation does not refer to \"{0}\" and \"{1}\" any longer.",
                                                   hostInformationExcluded.Uri == null ? string.Empty : hostInformationExcluded.Uri,
                                                   hostInformationExcluded.Url == null ? string.Empty : hostInformationExcluded.Url);
                    }

                    GenuineThreadPool.QueueUserWorkItem(new WaitCallback(this.ReleaseHostResources), new HostInformationAndReason(hostInformationExcluded, GenuineExceptions.Get_Channel_ClientDidNotReconnectWithinTimeOut(hostInformationExcluded.ToString())), true);
                }
            }
        }
        /// <summary>
        /// Closes the specified connections to the remote host and releases acquired resources.
        /// </summary>
        /// <param name="hostInformation">Host information.</param>
        /// <param name="genuineConnectionType">What kind of connections will be affected by this operation.</param>
        /// <param name="reason">The reason of resource releasing.</param>
        public override void ReleaseConnections(HostInformation hostInformation, GenuineConnectionType genuineConnectionType, Exception reason)
        {
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;
            ArrayList connectionsToClose = new ArrayList();

            using (new WriterAutoLocker(this._disposeLock))
            {
                if (this._disposed)
                    return ;

                // LOG:
                if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 )
                {
                    binaryLogWriter.WriteEvent(LogCategory.Connection, "HttpServerConnectionManager.ReleaseConnections",
                        LogMessageType.ReleaseConnections, reason, null, hostInformation, null,
                        GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                        null, null, -1, 0, 0, 0, Enum.Format(typeof(GenuineConnectionType), genuineConnectionType, "g"), null, null, null,
                        "Connections \"{0}\" will be terminated.", Enum.Format(typeof(GenuineConnectionType), genuineConnectionType, "g"), null);
                }

                // persistent
                if ( (genuineConnectionType & GenuineConnectionType.Persistent) != 0 )
                {
                    // persistent
                    ReleaseConnections_Parameters releaseConnections_Parameters = new ReleaseConnections_Parameters();
                    releaseConnections_Parameters.FailedConnections = connectionsToClose;
                    releaseConnections_Parameters.HostInformation = hostInformation;

                    this._persistent.InspectAllConnections(this._releaseConnections_InspectPersistentConnections, releaseConnections_Parameters);
                }

                // close connections
                foreach (HttpServerConnection nextHttpServerConnection in connectionsToClose)
                {
                    lock (nextHttpServerConnection.Listener_Lock)
                    {
                        // LOG:
                        if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 )
                        {
                            binaryLogWriter.WriteEvent(LogCategory.Connection, "HttpClientConnectionManager.ReleaseConnections",
                                LogMessageType.ConnectionShuttingDown, reason, null, nextHttpServerConnection.Remote, null,
                                GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null,
                                nextHttpServerConnection.DbgConnectionId, 0, 0, 0, null, null, null, null,
                                "The connection is being shut down manually.");
                        }

                        nextHttpServerConnection.SignalState(GenuineEventType.GeneralConnectionClosed, reason, null);

                        this._persistent.Remove(nextHttpServerConnection.Remote.Uri, nextHttpServerConnection.ConnectionName);
                        if (nextHttpServerConnection.Listener != null)
                            this.Pool_SendThroughListener(nextHttpServerConnection, HttpPacketType.ClosedManually);
                    }
                }
            }
        }
 /// <summary>
 /// Constructs an instance of the SecuritySession_ZpaClient class.
 /// </summary>
 /// <param name="name">Name of the SecuritySession being created.</param>
 /// <param name="remote">The remote host.</param>
 /// <param name="keyProvider_ZpaClient">The ZPA Client Key Provider containing a login and password.</param>
 public SecuritySession_ZpaClient(string name, HostInformation remote, KeyProvider_ZpaClient keyProvider_ZpaClient)
     : base(name, remote, keyProvider_ZpaClient.ZpaFeatureFlags)
 {
     this._keyProvider_ZpaClient = keyProvider_ZpaClient;
 }
        /// <summary>
        /// Establishes a connection to the remote host.
        /// </summary>
        /// <param name="remote">The HostInformation of the remote host.</param>
        /// <param name="genuineConnectionType">Type of the connection.</param>
        /// <param name="localUri">Local URI.</param>
        /// <param name="localPort">Local port.</param>
        /// <param name="connectionName">The name of the connection or a null reference.</param>
        /// <param name="remoteUri">Remote URI.</param>
        /// <param name="remoteHostUniqueIdentifier">The unique identifier of the HostInformation used by the remote host.</param>
        /// <returns>A connection.</returns>
        internal TcpSocketInfo LowLevel_OpenConnection(HostInformation remote, GenuineConnectionType genuineConnectionType, string localUri, int localPort, string connectionName, out string remoteUri, out int remoteHostUniqueIdentifier)
        {
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;

            using (new ReaderAutoLocker(this._disposeLock))
            {
                if (this._disposed)
                    throw OperationException.WrapException(this._disposeReason);
            }

            remoteUri = null;
            Stream inputStream = null;
            Stream outputStream = null;
            remoteHostUniqueIdentifier = 0;
            string url = remote.Url;

            // parse provided url and fetch a port and IP address
            int portNumber;
            string hostName = GenuineUtility.SplitToHostAndPort(url, out portNumber);

            // LOG:
            if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 )
            {
                binaryLogWriter.WriteEvent(LogCategory.Connection, "TcpConnectionManager.LowLevel_OpenConnection",
                    LogMessageType.ConnectionEstablishing, null, null, remote, null,
                    GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null,
                    -1, 0, 0, 0, null, null, null, null,
                    "The connection is being established to {0}.", hostName);
            }

            Socket socket = null;

            // the time we should finish connection establishing before
            int timeout = GenuineUtility.GetTimeout( (TimeSpan) this.ITransportContext.IParameterProvider[GenuineParameter.ConnectTimeout] );
            using (ConnectionEstablishingClosure connectionEstablishingClosure = new ConnectionEstablishingClosure(hostName, portNumber, this.ITransportContext.IParameterProvider))
            {
                connectionEstablishingClosure.StartOperation();
                if (! connectionEstablishingClosure.Completed.WaitOne( GenuineUtility.GetMillisecondsLeft(timeout), false))
                    throw GenuineExceptions.Get_Connect_CanNotConnectToRemoteHost(url, "Timeout expired.");

                if (connectionEstablishingClosure.Exception != null)
                    throw GenuineExceptions.Get_Connect_CanNotConnectToRemoteHost(url, connectionEstablishingClosure.Exception.Message);

                socket = connectionEstablishingClosure.CompleteOperation();
            }

            if (! socket.Connected)
                throw GenuineExceptions.Get_Connect_CanNotConnectToRemoteHost(url, "Socket.Connected property is false after connecting.");

            if (connectionName == null)
                connectionName = "$/__GC/" + hostName;
            TcpSocketInfo tcpSocketInfo = new TcpSocketInfo(socket, this.ITransportContext, connectionName
            #if DEBUG
                ,"Opened connection"
            #endif
                );
            tcpSocketInfo.GenuineConnectionType = genuineConnectionType;

            // LOG:
            if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 )
            {
                binaryLogWriter.WriteConnectionParameterEvent(LogCategory.Connection, "TcpConnectionManager.LowLevel_OpenConnection",
                    LogMessageType.ConnectionParameters, null, remote, this.ITransportContext.IParameterProvider,
                    GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, tcpSocketInfo.DbgConnectionId,
                    "The connection is being established to \"{0}\".", hostName);
            }

            // send protocol version and the type of the connection
            Message message = new Message(null, null, -1, new TransportHeaders(), Stream.Null);
            message.FinishTime = timeout;
            message.SerializedContent = MessageCoder.SerializeConnectionHeader(MessageCoder.PROTOCOL_VERSION, genuineConnectionType, tcpSocketInfo.ConnectionName).BaseStream;
            LowLevel_SendSync(message, tcpSocketInfo);
            tcpSocketInfo.MessagesSentSynchronously.ReleaseAllMessages();

            // get connection-level SS
            string connectionLevelSSName = null;
            switch(genuineConnectionType)
            {
                case GenuineConnectionType.Persistent:
                    connectionLevelSSName = this.ITransportContext.IParameterProvider[GenuineParameter.SecuritySessionForPersistentConnections] as string;
                    break;

                case GenuineConnectionType.Named:
                    connectionLevelSSName = this.ITransportContext.IParameterProvider[GenuineParameter.SecuritySessionForNamedConnections] as string;
                    break;

                case GenuineConnectionType.Invocation:
                    connectionLevelSSName = this.ITransportContext.IParameterProvider[GenuineParameter.SecuritySessionForInvocationConnections] as string;
                    break;
            }

            SecuritySession securitySession = null;
            if (connectionLevelSSName != null)
                securitySession = this.ITransportContext.IKeyStore.GetKey(connectionLevelSSName).CreateSecuritySession(connectionLevelSSName, null);

            // establish it
            if (securitySession != null && ! securitySession.IsEstablished)
            {
                // LOG:
                if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 )
                {
                    binaryLogWriter.WriteEvent(LogCategory.Connection, "TcpConnectionManager.LowLevel_OpenConnection",
                        LogMessageType.ConnectionSecurityIsEstablished, null, null, tcpSocketInfo.Remote, null,
                        GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, securitySession, connectionLevelSSName,
                        tcpSocketInfo.DbgConnectionId, 0, 0, 0, null, null, null, null,
                        "The Connection Level Security Session is being established.");
                }

                bool firstPass = true;
                for ( ; ; )
                {
                    inputStream = Stream.Null;

                    try
                    {
                        // prepare streams
                        if (! firstPass)
                            inputStream = this.LowLevel_ReadSync(tcpSocketInfo, timeout, false);
                        else
                            firstPass = false;

                        outputStream = securitySession.EstablishSession(inputStream, true);

                        if (outputStream == null)
                            break;

                        // send a packet to the remote host
                        message = new Message(null, null, -1, new TransportHeaders(), Stream.Null);
                        message.FinishTime = timeout;
                        message.SerializedContent = outputStream;
                        LowLevel_SendSync(message, tcpSocketInfo);
                        tcpSocketInfo.MessagesSentSynchronously.ReleaseAllMessages();

                        if (securitySession.IsEstablished)
                            break;
                    }
                    finally
                    {
                        if (inputStream != null)
                            inputStream.Close();
                        if (outputStream != null)
                            outputStream.Close();
                    }
                }
            }

            tcpSocketInfo.ConnectionLevelSecurity = securitySession;

            // now send connection info through the established connection
            using (GenuineChunkedStream serializedLocalInfo = new GenuineChunkedStream(false))
            {
                // serialize local info
                BinaryWriter binaryWriter = new BinaryWriter(serializedLocalInfo);
                binaryWriter.Write((string) localUri);

                // 2.5.2 fix
                //				binaryWriter.Write((int) localPort);
                binaryWriter.Write((int) -1);
                binaryWriter.Write((byte) genuineConnectionType);
                binaryWriter.Write((int) remote.LocalHostUniqueIdentifier);

                // and send it
                message = new Message(null, null, -1, new TransportHeaders(), Stream.Null);
                message.FinishTime = timeout;
                message.SerializedContent = serializedLocalInfo;
                LowLevel_SendSync(message, tcpSocketInfo);
                tcpSocketInfo.MessagesSentSynchronously.ReleaseAllMessages();

                // read remote info
                using (Stream remoteUriStream = this.LowLevel_ReadSync(tcpSocketInfo, timeout, false))
                {
                    BinaryReader binaryReader = new BinaryReader(remoteUriStream);
                    remoteUri = binaryReader.ReadString();
                    remoteHostUniqueIdentifier = binaryReader.ReadInt32();
                }
            }

            tcpSocketInfo.IsServer = false;
            return tcpSocketInfo;
        }
        /// <summary>
        /// Closes the specified connections to the remote host and releases acquired resources.
        /// </summary>
        /// <param name="hostInformation">Host information or a null reference to close all connection according to specified types.</param>
        /// <param name="genuineConnectionType">What kind of connections will be affected by this operation.</param>
        /// <param name="reason">Reason of resource releasing.</param>
        public override void ReleaseConnections(HostInformation hostInformation, GenuineConnectionType genuineConnectionType, Exception reason)
        {
            TcpSocketInfo tcpSocketInfo = null;
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;

            // LOG:
            if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 )
            {
                binaryLogWriter.WriteEvent(LogCategory.Connection, "TcpConnectionManager.ReleaseConnections",
                    LogMessageType.ReleaseConnections, reason, null, hostInformation, null,
                    GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                    null, null, -1, 0, 0, 0, Enum.Format(typeof(GenuineConnectionType), genuineConnectionType, "g"), null, null, null,
                    "Connections \"{0}\" are terminated.", Enum.Format(typeof(GenuineConnectionType), genuineConnectionType, "g"), null);
            }

            // go through all connections and close such of them that fall under the specified category
            ArrayList failedConnections = new ArrayList();

            // persistent
            ReleaseConnections_Parameters releaseConnections_Parameters = new ReleaseConnections_Parameters();
            releaseConnections_Parameters.FailedConnections = failedConnections;
            releaseConnections_Parameters.HostInformation = hostInformation;
            releaseConnections_Parameters.GenuineConnectionType = genuineConnectionType;

            this._persistent.InspectAllConnections(this._releaseConnections_InspectPersistentConnections, releaseConnections_Parameters);

            // named
            if ( (genuineConnectionType & GenuineConnectionType.Persistent) != 0 || (genuineConnectionType & GenuineConnectionType.Named) != 0)
                lock (this._named)
                {
                    foreach (DictionaryEntry entry in this._named)
                    {
                        tcpSocketInfo = (TcpSocketInfo) entry.Value;
                        if (hostInformation != null && tcpSocketInfo.Remote != hostInformation)
                            continue;
                        if ( (genuineConnectionType & tcpSocketInfo.GenuineConnectionType) == 0)
                            continue;

                        failedConnections.Add(tcpSocketInfo);
                    }
                }

            // invocation
            if ( (genuineConnectionType & GenuineConnectionType.Invocation) != 0)
            {
                lock (this._invocation.SyncRoot)
                    foreach (DictionaryEntry entry in this._invocation)
                    {
                        ArrayList connections = (ArrayList) entry.Value;
                        lock (connections)
                        {
                            foreach (TcpSocketInfo nextTcpSocketInfo in connections)
                            {
                                if (hostInformation != null && nextTcpSocketInfo.Remote != hostInformation)
                                    continue;

                                failedConnections.Add(nextTcpSocketInfo);
                            }
                        }
                    }

                lock (this._knownInvocationConnections.SyncRoot)
                    foreach (DictionaryEntry entry in this._knownInvocationConnections)
                    {
                        tcpSocketInfo = (TcpSocketInfo) entry.Value;
                        if (hostInformation != null && tcpSocketInfo.Remote != hostInformation)
                            continue;

                        failedConnections.Add(tcpSocketInfo);
                    }
            }

            // close connections
            foreach (TcpSocketInfo failedTcpSocketInfo in failedConnections)
            {
                // LOG:
                if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0 )
                {
                    binaryLogWriter.WriteEvent(LogCategory.Connection, "TcpConnectionManager.ReleaseConnections",
                        LogMessageType.ConnectionShuttingDown, reason, null, failedTcpSocketInfo.Remote, null,
                        GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                        null, null, failedTcpSocketInfo.DbgConnectionId, 0, 0, 0, null, null, null, null,
                        "The connection is terminated.");
                }

                this.SocketFailed(GenuineExceptions.Get_Channel_ConnectionShutDown(reason), failedTcpSocketInfo);

                if (failedTcpSocketInfo.GenuineConnectionType == GenuineConnectionType.Persistent)
                    failedTcpSocketInfo.SignalState(GenuineEventType.GeneralConnectionClosed, reason, null);
            }
        }
        /// <summary>
        /// Opens a connection to the host specified by the url.
        /// </summary>
        /// <param name="remote">The HostInformation of the Remote Host.</param>
        /// <param name="localUri">The uri of the local host.</param>
        /// <param name="remoteUri">The uri of the remote host.</param>
        /// <param name="remoteHostUniqueIdentifier">The unique identifier of the HostInformation used by the remote host.</param>
        /// <returns>The established connection.</returns>
        private SharedMemoryConnection LowLevel_OpenConnection(HostInformation remote, string localUri, out string remoteUri, out int remoteHostUniqueIdentifier)
        {
            using (new ReaderAutoLocker(this._disposeLock))
            {
                if (this._disposed)
                    throw OperationException.WrapException(this._disposeReason);
            }

            remoteUri = null;
            Stream inputStream = null;
            Stream outputStream = null;
            string url = remote.Url;

            // the maximum time during which the connection must be established
            int timeout = GenuineUtility.GetTimeout((TimeSpan) this.ITransportContext.IParameterProvider[GenuineParameter.ConnectTimeout]);

            IParameterProvider parameters = this.ITransportContext.IParameterProvider;

            string mutexName = GenuineSharedMemoryChannel.ConstructSharedObjectName(
                "MUTEX" + url, parameters);
            string clientConnected = GenuineSharedMemoryChannel.ConstructSharedObjectName(
                "CC" + url, parameters);
            string clientAccepted = GenuineSharedMemoryChannel.ConstructSharedObjectName(
                "CA" + url, parameters);

            // open the server share
            SharedMemoryConnection serverSharedMemoryConnection = new SharedMemoryConnection(this.ITransportContext, url, false, false);

            // LOG:
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;
            if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 )
            {
                binaryLogWriter.WriteConnectionParameterEvent(LogCategory.Connection, "SharedMemoryConnectionManager.LowLevel_OpenConnection",
                    LogMessageType.ConnectionParameters, null, remote, this.ITransportContext.IParameterProvider,
                    GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, serverSharedMemoryConnection.DbgConnectionId,
                    "A Shared Memory connection is being established.");
            }

            // and create the local share
            string shareName = "gshmem://" + Guid.NewGuid().ToString("N");
            SharedMemoryConnection sharedMemoryConnection = new SharedMemoryConnection(this.ITransportContext, shareName, true, true);

            BinaryWriter connectionInformation = MessageCoder.SerializeConnectionHeader(MessageCoder.PROTOCOL_VERSION, GenuineConnectionType.Persistent, "Default");
            connectionInformation.Write(shareName);

            // let the server know that a client's share is ready
            Mutex mutex = null;
            try
            {
                mutex = WindowsAPI.OpenMutex(mutexName);

                NamedEvent _clientConnected = NamedEvent.OpenNamedEvent(clientConnected);
                NamedEvent _clientAccepted = NamedEvent.OpenNamedEvent(clientAccepted);

                if (! GenuineUtility.WaitOne(mutex, GenuineUtility.GetMillisecondsLeft(timeout)) )
                    throw GenuineExceptions.Get_Connect_CanNotConnectToRemoteHost(url, "Can not acquire the lock for the global mutex.");

                // wait until server accepts this client
                _clientAccepted.ManualResetEvent.Reset();
                _clientConnected.ManualResetEvent.Set();

                // copy client's name
                serverSharedMemoryConnection.LowLevel_SendSync(connectionInformation.BaseStream, timeout);

                if (! GenuineUtility.WaitOne(_clientAccepted.ManualResetEvent, GenuineUtility.GetMillisecondsLeft(timeout)) )
                    throw GenuineExceptions.Get_Connect_CanNotConnectToRemoteHost(url, "Remote server did not accept a request within the specified time span.");
            }
            finally
            {
                if (mutex != null)
                {
                    try
                    {
                        mutex.ReleaseMutex();
                    }
                    catch
                    {
                    }

                    try
                    {
                        mutex.Close();
                    }
                    catch
                    {
                    }
                }
            }

            // get the connection-level Security Session
            string connectionLevelSSName = this.ITransportContext.IParameterProvider[GenuineParameter.SecuritySessionForPersistentConnections] as string;
            SecuritySession securitySession = null;
            if (connectionLevelSSName != null)
                securitySession = this.ITransportContext.IKeyStore.GetKey(connectionLevelSSName).CreateSecuritySession(connectionLevelSSName, null);

            // establish it
            if (securitySession != null && ! securitySession.IsEstablished)
            {
                bool firstPass = true;
                for ( ; ; )
                {
                    inputStream = Stream.Null;

                    try
                    {
                        // prepare streams
                        if (! firstPass)
                            inputStream = sharedMemoryConnection.LowLevel_ReadSync(timeout);
                        else
                            firstPass = false;

                        outputStream = securitySession.EstablishSession(inputStream, true);

                        if (outputStream == null)
                            break;

                        // send a packet to the remote host
                        sharedMemoryConnection.LowLevel_SendSync(outputStream, timeout);
                        if (securitySession.IsEstablished)
                            break;
                    }
                    finally
                    {
                        if (inputStream != null)
                            inputStream.Close();
                        if (outputStream != null)
                            outputStream.Close();
                    }
                }
            }

            sharedMemoryConnection.ConnectionLevelSecurity = securitySession;

            // now send connection info through the established connection
            using (GenuineChunkedStream serializedLocalInfo = new GenuineChunkedStream(false))
            {
                // serialize local info
                BinaryWriter binaryWriter = new BinaryWriter(serializedLocalInfo);
                binaryWriter.Write((string) localUri);
                binaryWriter.Write((int) remote.LocalHostUniqueIdentifier);

                // and send it
                sharedMemoryConnection.LowLevel_SendSync(serializedLocalInfo, timeout);

                // read remote info
                using (Stream remoteUriStream = sharedMemoryConnection.LowLevel_ReadSync(timeout))
                {
                    BinaryReader binaryReader = new BinaryReader(remoteUriStream);
                    remoteUri = binaryReader.ReadString();
                    remoteHostUniqueIdentifier = binaryReader.ReadInt32();
                }
            }

            sharedMemoryConnection.Remote = remote;
            sharedMemoryConnection.Remote.UpdateUri(remoteUri, remoteHostUniqueIdentifier);
            sharedMemoryConnection.Remote.GenuinePersistentConnectionState = GenuinePersistentConnectionState.Opened;

            // LOG:
            if ( binaryLogWriter != null && binaryLogWriter[LogCategory.HostInformation] > 0 )
            {
                binaryLogWriter.WriteHostInformationEvent("SharedMemoryConnectionManager.LowLevel_OpenConnection",
                    LogMessageType.HostInformationCreated, null, remote,
                    GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null,
                    sharedMemoryConnection.DbgConnectionId,
                    "HostInformation is ready for actions.");
            }

            // LOG:
            if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 )
            {
                binaryLogWriter.WriteEvent(LogCategory.Connection, "SharedMemoryConnectionManager.LowLevel_OpenConnection",
                    LogMessageType.ConnectionEstablished, null, null, remote, null,
                    GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                    securitySession, connectionLevelSSName,
                    sharedMemoryConnection.DbgConnectionId, (int) GenuineConnectionType.Persistent, 0, 0, this.GetType().Name, null, null, null,
                    "The connection to the remote host is established.");
            }

            return sharedMemoryConnection;
        }
        /// <summary>
        /// Releases resources belonging to the remote host.
        /// </summary>
        /// <param name="hostInformation">The remote host.</param>
        /// <param name="reason">The exception.</param>
        /// <returns>True if host resources have been released by this call. False if host resources have been already released.</returns>
        public bool ReleaseHostResources(HostInformation hostInformation, Exception reason)
        {
            if (hostInformation.Uri != null)
                this.RemoveHostInformation(hostInformation.Uri, hostInformation);
            if (hostInformation.Url != null)
                this.RemoveHostInformation(hostInformation.Url, hostInformation);

            // release all resources associated with this host
            bool cleanup = hostInformation.Dispose(reason);
            if (cleanup)
            {
                this.ITransportContext.ConnectionManager.ReleaseConnections(hostInformation, GenuineConnectionType.All, reason);
                this.ITransportContext.IIncomingStreamHandler.DispatchException(hostInformation, reason);

                // and fire a warning
                this.ITransportContext.IGenuineEventProvider.Fire(new GenuineEventArgs(GenuineEventType.HostResourcesReleased, reason, hostInformation, null));
            }

            return cleanup;
        }
Exemple #24
0
 /// <summary>
 /// Updates a reference to the host.
 /// </summary>
 /// <param name="uriOrUrl">The reference.</param>
 /// <param name="hostInformation">The host.</param>
 internal void UpdateHost(string uriOrUrl, HostInformation hostInformation)
 {
     this.SetHostInformation(uriOrUrl, hostInformation);
 }
        /// <summary>
        /// Removes the specified element from the collection associated with the specified key.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="hostInformation">The element being removed.</param>
        private void RemoveHostInformation(string key, HostInformation hostInformation)
        {
            lock (this.SyncRoot)
            {
                ArrayList arrayList = this._hashtable[key] as ArrayList;

                // if there is no collection corresponding to the key
                if (arrayList == null)
                    return ;

                // check whether this element is already in the collection
                for ( int i = 0; i < arrayList.Count; i++ )
                    if (object.ReferenceEquals(arrayList[i], hostInformation))
                    {
                        arrayList.RemoveAt(i);
                        break;
                    }

                // if the collection is empty, delete it with the entry.
                if (arrayList.Count <= 0)
                    this._hashtable.Remove(key);
            }
        }
 /// <summary>
 /// Constructs an instance of the ConnectionSignaller class.
 /// </summary>
 /// <param name="remote">The remote host.</param>
 /// <param name="iGenuineEventProvider">The event provider.</param>
 public ConnectionStateSignaller(HostInformation remote, IGenuineEventProvider iGenuineEventProvider)
 {
     this._remote = remote;
     this._iGenuineEventProvider = iGenuineEventProvider;
     this._currentState = GenuineEventType.GeneralConnectionIndeterminate;
 }
 /// <summary>
 /// Constructs an instance of the HostInformationAndReason class.
 /// </summary>
 /// <param name="hostInformation">The remote host.</param>
 /// <param name="reason">The exception.</param>
 public HostInformationAndReason(HostInformation hostInformation, Exception reason)
 {
     this.HostInformation = hostInformation;
     this.Reason = reason;
 }
        /// <summary>
        /// Processes the sender's request.
        /// </summary>
        /// <param name="genuineConnectionType">The type of the connection.</param>
        /// <param name="input">The incoming data.</param>
        /// <param name="httpServerRequestResult">The request.</param>
        /// <param name="httpServerConnection">The connection.</param>
        /// <param name="sequenceNo">The sequence number.</param>
        /// <param name="remote">The information about remote host.</param>
        public void LowLevel_ProcessSenderRequest(GenuineConnectionType genuineConnectionType, Stream input, HttpServerRequestResult httpServerRequestResult, HttpServerConnection httpServerConnection, int sequenceNo, HostInformation remote)
        {
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;
            GenuineChunkedStream outputStream = null;

            // parse the incoming stream
            bool directExecution = genuineConnectionType != GenuineConnectionType.Persistent;
            BinaryReader binaryReader = new BinaryReader(input);

            using (BufferKeeper bufferKeeper = new BufferKeeper(0))
            {
                switch(genuineConnectionType)
                {
                    case GenuineConnectionType.Persistent:
                        Exception gotException = null;

                        try
                        {
                            if (httpServerConnection.Sender_SecuritySession != null)
                            {
                                input = httpServerConnection.Sender_SecuritySession.Decrypt(input);
                                binaryReader = new BinaryReader(input);
                            }

                            while (binaryReader.ReadByte() == 0)
                                using(LabelledStream labelledStream = new LabelledStream(this.ITransportContext, input, bufferKeeper.Buffer))
                                {
                                    GenuineChunkedStream receivedContent = new GenuineChunkedStream(true);
                                    GenuineUtility.CopyStreamToStream(labelledStream, receivedContent);
                                    this.ITransportContext.IIncomingStreamHandler.HandleMessage(receivedContent, httpServerConnection.Remote, genuineConnectionType, httpServerConnection.ConnectionName, httpServerConnection.DbgConnectionId, false, this._iMessageRegistrator, httpServerConnection.Sender_SecuritySession, httpServerRequestResult);
                                }
                        }
                        catch(Exception ex)
                        {
                            gotException = ex;

                            // LOG:
                            if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 )
                            {
                                binaryLogWriter.WriteEvent(LogCategory.Connection, "HttpServerConnectionManager.LowLevel_ProcessSenderRequest",
                                    LogMessageType.Error, ex, null, httpServerConnection.Remote, null,
                                    GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null,
                                    httpServerConnection.DbgConnectionId, 0, 0, 0, null, null, null, null,
                                    "Error occurred while processing the sender request N: {0}.", httpServerConnection.Sender_SequenceNo);
                            }
                        }

                        if (gotException != null)
                        {
                            gotException = OperationException.WrapException(gotException);
                            outputStream = this.LowLevel_CreateStreamWithHeader(HttpPacketType.SenderError, sequenceNo, remote);
                            BinaryFormatter binaryFormatter = new BinaryFormatter(new RemotingSurrogateSelector(), new StreamingContext(StreamingContextStates.Other));
                            binaryFormatter.Serialize(outputStream, gotException);
                        }
                        else
                        {
                            // serialize and send the empty response
                            outputStream = this.LowLevel_CreateStreamWithHeader(HttpPacketType.SenderResponse, sequenceNo, remote);
                            MessageCoder.FillInLabelledStream(null, null, null, outputStream,
                                bufferKeeper.Buffer, (int) this.ITransportContext.IParameterProvider[GenuineParameter.HttpRecommendedPacketSize]);
                        }
                        break;

                    case GenuineConnectionType.Invocation:
                        // register the http context as an invocation waiters
                        string connectionGuid = Guid.NewGuid().ToString("N");

                        try
                        {
                            if (binaryReader.ReadByte() != 0)
                            {
                                // LOG:
                                if ( binaryLogWriter != null )
                                {
                                    binaryLogWriter.WriteImplementationWarningEvent("HttpServerConnectionManager.LowLevel_ProcessSenderRequest", LogMessageType.Error,
                                        GenuineExceptions.Get_Debugging_GeneralWarning("The invocation request doesn't contain any messages."),
                                        GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                        "The invocation request doesn't contain any messages.");
                                }
                            }

                            using(LabelledStream labelledStream = new LabelledStream(this.ITransportContext, input, bufferKeeper.Buffer))
                            {
                                // process the response
                                this._invocation[connectionGuid] = null;
                                this.ITransportContext.IIncomingStreamHandler.HandleMessage(labelledStream, remote, genuineConnectionType, connectionGuid, -1, true, null, null, httpServerRequestResult);
                            }

                            if (binaryReader.ReadByte() != 1)
                            {
                                // LOG:
                                if ( binaryLogWriter != null )
                                {
                                    binaryLogWriter.WriteImplementationWarningEvent("HttpServerConnectionManager.LowLevel_ProcessSenderRequest", LogMessageType.Error,
                                        GenuineExceptions.Get_Debugging_GeneralWarning("The invocation request must not contain more than one message."),
                                        GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                        "The invocation request must not contain more than one message.");
                                }
                            }

                            // if there is a response, serialize it
                            outputStream = this.LowLevel_CreateStreamWithHeader(HttpPacketType.Usual, sequenceNo, remote);
                            Message message = this._invocation[connectionGuid] as Message;
                            MessageCoder.FillInLabelledStream(message, null, null, outputStream,
                                bufferKeeper.Buffer, (int) this.ITransportContext.IParameterProvider[GenuineParameter.HttpRecommendedPacketSize]);
                        }
                        finally
                        {
                            this._invocation.Remove(connectionGuid);
                        }
                        break;
                }
            }

            // report back to the client
            Stream finalStream = outputStream;
            this.LowLevel_SendStream(httpServerRequestResult.HttpContext, false, null, true, ref finalStream, httpServerConnection);
        }
 /// <summary>
 /// Closes the specified connections to the remote host and releases acquired resources.
 /// </summary>
 /// <param name="hostInformation">Host information.</param>
 /// <param name="genuineConnectionType">What kind of connections will be affected by this operation.</param>
 /// <param name="reason">Reason of resource releasing.</param>
 public override void ReleaseConnections(HostInformation hostInformation, GenuineConnectionType genuineConnectionType, Exception reason)
 {
 }
 /// <summary>
 /// Creates and returns the stream with a written response header.
 /// </summary>
 /// <param name="httpPacketType">The type of the packet.</param>
 /// <param name="sequenceNo">The sequence number.</param>
 /// <param name="remote">The HostInformation of the remote host.</param>
 /// <returns>The stream with a written response header.</returns>
 public GenuineChunkedStream LowLevel_CreateStreamWithHeader(HttpPacketType httpPacketType, int sequenceNo, HostInformation remote)
 {
     GenuineChunkedStream output = new GenuineChunkedStream(false);
     BinaryWriter binaryWriter = new BinaryWriter(output);
     HttpMessageCoder.WriteResponseHeader(binaryWriter, remote.ProtocolVersion, this.ITransportContext.ConnectionManager.Local.Uri, sequenceNo, httpPacketType, remote.LocalHostUniqueIdentifier);
     return output;
 }
 /// <summary>
 /// Releases information belonging to the failed connection.
 /// </summary>
 /// <param name="hostInformation">The reason of releasing.</param>
 /// <param name="exception">The reason of the resource releasing.</param>
 internal void ReleaseHostResources(HostInformation hostInformation, Exception exception)
 {
     this.ITransportContext.IGenuineEventProvider.Fire(new GenuineEventArgs(GenuineEventType.GeneralServerRestartDetected, exception, hostInformation, null));
 }
 /// <summary>
 /// Constructs a fake instance of the HostInformation for debugging and diagnostic purposes.
 /// </summary>
 /// <returns>An instance of the HostInformation class filled with fake stuff.</returns>
 public static HostInformation ConstructInstanceForDebugging()
 {
     HostInformation hostInformation = new HostInformation("gtcp://fakehost:8737/fake.rem", null);
     hostInformation._uri = "gtcp://8089";
     hostInformation._remoteHostUniqueIdentifier = 15;
     return hostInformation;
 }
        /// <summary>
        /// Dispatches the exception to all response processors awaiting something from the specific remote host.
        /// </summary>
        /// <param name="hostInformation">The remote host.</param>
        /// <param name="exception">The exception.</param>
        public void DispatchException(HostInformation hostInformation, Exception exception)
        {
            // LOG:
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;
            if ( binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0 )
                binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "GenuineReceivingHandler.DispatchException",
                    LogMessageType.ExceptionDispatched, exception,
                    null, hostInformation,
                    null,
                    GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null,
                    -1, 0, 0, 0, null, null, null, null,
                    "The exception is being dispatched back to the caller context.");

            Hashtable expiredHandlers = new Hashtable();

            lock (GenuineReceivingHandler._responseHandlers.SyncRoot)
            {
                foreach (DictionaryEntry entry in GenuineReceivingHandler._responseHandlers)
                {
                    IResponseProcessor iResponseProcessor = entry.Value as IResponseProcessor;

                    // 2.5.2 fix; fixed in 2.5.6 again
                    bool hostsEqual = (iResponseProcessor.Remote == hostInformation);

                    if (! hostsEqual && iResponseProcessor.Remote != null && hostInformation != null)
                        hostsEqual = (iResponseProcessor.Remote.Url == hostInformation.Url && hostInformation.Url != null)
                            || (iResponseProcessor.Remote.Uri == hostInformation.Uri && hostInformation.Uri != null);

                    if (hostsEqual)
                        expiredHandlers[entry.Key] = iResponseProcessor;
                }

                foreach (DictionaryEntry entry in expiredHandlers)
                {
                    IResponseProcessor iResponseProcessor = entry.Value as IResponseProcessor;

                    // LOG:
                    if ( binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0 )
                        binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "GenuineReceivingHandler.DispatchException",
                            LogMessageType.ExceptionDispatched, exception,
                            iResponseProcessor.Message, hostInformation,
                            null,
                            GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null,
                            -1, 0, 0, 0, null, null, null, null,
                            "The exception is being dispatched back to the caller context.");

                    iResponseProcessor.DispatchException(OperationException.WrapException(exception));

            #if TRIAL
            #else
                    GenuineReceivingHandler._responseHandlers.Remove(entry.Key);
            #endif

                }
            }
        }
        /// <summary>
        /// Closes the specified connections to the remote host and releases acquired resources.
        /// </summary>
        /// <param name="hostInformation">The host information.</param>
        /// <param name="genuineConnectionType">A value indicating what kind of connections will be affected by this operation.</param>
        /// <param name="reason">The reason of resource releasing.</param>
        public override void ReleaseConnections(HostInformation hostInformation, GenuineConnectionType genuineConnectionType, Exception reason)
        {
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;
            reason = GenuineExceptions.Get_Channel_ConnectionShutDown(reason);

            // LOG:
            if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 )
            {
                binaryLogWriter.WriteEvent(LogCategory.Connection, "SharedMemoryConnectionManager.ReleaseConnections",
                    LogMessageType.ReleaseConnections, reason, null, hostInformation, null,
                    GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                    null, null, -1, 0, 0, 0, Enum.Format(typeof(GenuineConnectionType), genuineConnectionType, "g"), null, null, null,
                    "Connections \"{0}\" will be terminated.", Enum.Format(typeof(GenuineConnectionType), genuineConnectionType, "g"), null);
            }

            if (hostInformation == null)
            {
                this.InternalDispose(reason);
                return ;
            }

            SharedMemoryConnection sharedMemoryConnection = null;
            if (hostInformation.Url != null)
                sharedMemoryConnection = this._persistent[hostInformation.Url] as SharedMemoryConnection;
            if (sharedMemoryConnection != null)
                this.ConnectionFailed(reason, sharedMemoryConnection);

            sharedMemoryConnection = null;
            if (hostInformation.Uri != null)
                sharedMemoryConnection = this._persistent[hostInformation.Uri] as SharedMemoryConnection;
            if (sharedMemoryConnection != null)
                this.ConnectionFailed(reason, sharedMemoryConnection);
        }
 /// <summary>
 /// Constructs an instance of the SecuritySession_SspiClient class.
 /// </summary>
 /// <param name="name">The name of the Security Session.</param>
 /// <param name="remote">The remote host.</param>
 /// <param name="keyProvider_SspiClient">Parent KeyProvider_SspiClient instance to get settings from.</param>
 public SecuritySession_SspiClient(string name, HostInformation remote, KeyProvider_SspiClient keyProvider_SspiClient)
     : base(name, remote)
 {
     this.KeyProvider_SspiClient = keyProvider_SspiClient;
 }
 /// <summary>
 /// Creates SecuritySession which will perform all traffic processing in
 /// specific security context.
 /// </summary>
 /// <param name="name">The name of the SecuritySession being created.</param>
 /// <param name="remote">The remote host.</param>
 /// <returns>SecuritySession that will perform all traffic processing that is performed in specific security context.</returns>
 public SecuritySession CreateSecuritySession(string name, HostInformation remote)
 {
     return new SecuritySession_SelfEstablishingSymmetric(name, remote);
 }