/// <summary> /// Initiates an asynchronous operation. /// </summary> public void StartAsynchronousOperation() { // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; try { this._socket.BeginSend(this._buffer, this._offset, this._size, SocketFlags.None, this._asyncCallback, this._state); // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.LowLevelTransport] > 0) { binaryLogWriter.WriteEvent(LogCategory.LowLevelTransport, "Async_InitiateSocketSending.StartAsynchronousOperation", LogMessageType.LowLevelTransport_AsyncSendingInitiated, null, null, null, new MemoryStream(this._buffer, this._offset, this._size), GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, this._buffer.GetHashCode(), this._offset, this._size, null, null, null, null, "Sending has been initiated. Socket: {0}.", (long)this._socket.Handle); } } catch (Exception ex) { // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.LowLevelTransport] > 0) { binaryLogWriter.WriteEvent(LogCategory.LowLevelTransport, "Async_InitiateSocketSending.StartAsynchronousOperation", LogMessageType.LowLevelTransport_AsyncSendingInitiated, ex, null, null, new MemoryStream(this._buffer, this._offset, this._size), GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, this._buffer.GetHashCode(), this._offset, this._size, null, null, null, null, "Sending cannot be initiated. Socket: {0}.", (long)this._socket.Handle); } } }
/// <summary> /// Associates the provided key provider with the specified Security Session name. /// Removes the record if iKeyProvider is a null reference. /// </summary> /// <param name="name">The name of Security Context.</param> /// <param name="iKeyProvider">The key provider or a null reference.</param> public static void SetGlobalKey(string name, IKeyProvider iKeyProvider) { BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (iKeyProvider == null) { // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0) { binaryLogWriter.WriteEvent(LogCategory.Security, "SecuritySessionServices.SetGlobalKey", LogMessageType.KeyProviderDissociated, null, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, iKeyProvider.ToString(), name, null, null, "The Key Provider (\"{0}\") has been dissociated from the \"{1}\" name.", iKeyProvider.ToString(), name); } _globalKeys.Remove(name); } else { if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0) { binaryLogWriter.WriteEvent(LogCategory.Security, "SecuritySessionServices.SetGlobalKey", LogMessageType.KeyProviderAssociated, null, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, iKeyProvider.ToString(), name, null, null, "The Key Provider (\"{0}\") has been associated with the \"{1}\" name.", iKeyProvider.ToString(), name); } _globalKeys[name] = iKeyProvider; } }
/// <summary> /// Initiates an asynchronous operation. /// </summary> public void StartAsynchronousOperation() { // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; try { this._socket.BeginReceive(this._buffer, this._offset, this._size, SocketFlags.None, this._asyncCallback, this._state); // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.LowLevelTransport] > 0) { binaryLogWriter.WriteEvent(LogCategory.LowLevelTransport, "Async_InitiateSocketReceiving.StartAsynchronousOperation", LogMessageType.LowLevelTransport_AsyncReceivingInitiated, null, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, null, null, null, null, "Socket.BeginReceive(). Socket: {0}. Buffer: {1}. Offset: {2}. Size: {3}.", (long)this._socket.Handle, this._buffer.GetHashCode(), this._offset, this._size); } } catch (Exception ex) { // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.LowLevelTransport] > 0) { binaryLogWriter.WriteEvent(LogCategory.LowLevelTransport, "Async_InitiateSocketReceiving.StartAsynchronousOperation", LogMessageType.LowLevelTransport_AsyncReceivingInitiated, ex, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, this._buffer.GetHashCode(), this._offset, this._size, null, null, null, null, "Socket.BeginReceive(). Socket: {0}. Buffer: {1}. Offset: {2}. Size: {3}.", (long)this._socket.Handle, this._buffer.GetHashCode(), this._offset, this._size); } } }
/// <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> /// Checks whether the timeout has expired. /// </summary> public void TimerCallback() { lock (this) { if (this._isCompleted || this._isAborted) { return; } if (GenuineUtility.IsTimeoutExpired(this._timeoutExpiresAt)) { // TODO: remove this // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null) { binaryLogWriter.WriteEvent(LogCategory.Debugging, "HttpWebRequestCop.TimerCallback", LogMessageType.DebuggingWarning, null, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, null, null, null, null, "Stopping the web request."); } this._isAborted = true; this._httpWebRequest.Abort(); } } }
/// <summary> /// Requests processing from the current sink of the response from a method call sent asynchronously. /// It's a reply to a previously processed async call. /// Parameter state is expected to contain source message. /// </summary> /// <param name="sinkStack">A stack of sinks leading back to the server transport sink.</param> /// <param name="state">Information generated on the request side that is associated with this sink.</param> /// <param name="msg">The response message.</param> /// <param name="headers">The headers to add to the return message heading to the client.</param> /// <param name="stream">The stream heading back to the transport sink.</param> public void AsyncProcessResponse(IServerResponseChannelSinkStack sinkStack, object state, IMessage msg, ITransportHeaders headers, Stream stream) { Message message = (Message)state; BinaryLogWriter binaryLogWriter = message.ITransportContext.BinaryLogWriter; Message reply = new Message(message, headers, stream); // LOG: put down the log record if (binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0) { string invocationTarget = msg.Properties["__Uri"] as string; string methodName = BinaryLogWriter.ParseInvocationMethod(msg.Properties["__MethodName"] as string, msg.Properties["__TypeName"] as string); binaryLogWriter.WriteMessageCreatedEvent("GenuineUniversalServerTransportSink.AsyncProcessResponse", LogMessageType.MessageCreated, null, reply, false, reply.Recipient, this.ITransportContext.BinaryLogWriter[LogCategory.MessageProcessing] > 1 ? reply.Stream : null, invocationTarget, methodName, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, -1, -1, null, -1, null, "The response message has been created."); reply.ITransportHeaders[Message.TransportHeadersInvocationTarget] = invocationTarget; reply.ITransportHeaders[Message.TransportHeadersMethodName] = methodName; binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "GenuineUniversalServerTransportSink.AsyncProcessResponse", LogMessageType.MessageRequestInvoked, null, reply, message.Sender, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, GenuineUtility.TickCount, 0, message.SeqNo, null, null, null, null, "The .NET Remoting invocation has been performed."); } message.ITransportContext.ConnectionManager.Send(reply); }
/// <summary> /// Initializes encryptor and decryptor. /// </summary> protected override void SessionEstablished() { lock (this) { Rijndael rijndael = Rijndael.Create(); rijndael.Key = this.RijndaelKey; rijndael.Mode = CipherMode.ECB; if (this._encryptor == null) { this._encryptor = rijndael.CreateEncryptor(); this._decryptor = rijndael.CreateDecryptor(); } // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0) { binaryLogWriter.WriteEvent(LogCategory.Security, "SecuritySession_SelfEstablishingSymmetric.SessionEstablished", LogMessageType.SecuritySessionKey, null, null, this.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, this, this.Name, -1, 0, 0, 0, "Encryption with " + rijndael.GetType().ToString(), null, null, null, "Security Session security information is initialized."); } } base.SessionEstablished(); }
/// <summary> /// Informs all dependent entities that the Security Session has been established. /// </summary> protected override void SessionEstablished() { // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0) { WindowsIdentity windowsIdentity = this.WindowsIdentity; binaryLogWriter.WriteEvent(LogCategory.Security, "SecuritySession_SspiServer.SessionEstablished", LogMessageType.SecuritySessionKey, null, null, this.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, this, this.Name, -1, 0, 0, 0, string.Format("SSPI Package: {0} Features: {1} Win Auth Type: {2} IsAnonymous: {3} IsGuest: {4} IsSystem: {5} Name: {6}", this.KeyProvider_SspiServer.PackageName, Enum.Format(typeof(SspiFeatureFlags), this.KeyProvider_SspiServer.RequiredFeatures, "g"), windowsIdentity.AuthenticationType, windowsIdentity.IsAnonymous, windowsIdentity.IsGuest, windowsIdentity.IsSystem, windowsIdentity.Name), null, null, null, "Security Session security information is initialized."); } this._isEstablished.Set(); SendAssociatedMessages(); }
/// <summary> /// Stops listening to the specified end point. Does not close any connections. /// </summary> /// <param name="endPoint">The end point</param> public override void StopListening(object endPoint) { lock (this) { if (this._socket == null) { return; } // LOG: BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0) { binaryLogWriter.WriteEvent(LogCategory.Connection, "UdpConnectionManager.StopListening", LogMessageType.ListeningStopped, null, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, this.DbgConnectionId, 0, 0, 0, null, null, null, null, "The listening socket is not longer associated with the {0} local end point.", endPoint == null ? string.Empty : endPoint.ToString()); } SocketUtility.CloseSocket(this._socket); this._socket = null; this._closing = true; } if (!this._receivingThreadClosed.WaitOne(TimeSpan.FromMinutes(2), false)) { throw GenuineExceptions.Get_Processing_LogicError("Receiving thread didn't exit within 2 minutes."); } }
/// <summary> /// Releases all acquired resources. /// Warning: must be called only by the instance of the KnownHosts class. /// </summary> /// <param name="reason">The reason of resource releasing.</param> /// <returns>False if host resources have already been released before this call.</returns> internal bool Dispose(Exception reason) { if (this.IsDisposed) { return(false); } lock (this.DisposeLock) { if (this.IsDisposed) { return(false); } this._isDisposed = true; this.DisposeReason = reason; // LOG: BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.HostInformation] > 0) { string stackTrace = String.Empty; try { stackTrace = Environment.StackTrace; } catch { } binaryLogWriter.WriteEvent(LogCategory.HostInformation, "HostInformation.Dispose", LogMessageType.HostInformationReleased, reason, null, this, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, this.Uri, this.Url, null, null, "The HostInformation is released. The caller: {0}.", stackTrace); } // release all Security Sessions that need this lock (this._securitySessions) { foreach (DictionaryEntry entry in this._securitySessions) { IDisposable iDisposable = entry.Value as IDisposable; if (iDisposable != null) { iDisposable.Dispose(); } } this._securitySessions.Clear(); } } return(true); }
/// <summary> /// Sends a ping through the specified connection. /// </summary> /// <param name="sharedMemoryConnectionAsObject">The connection.</param> private void SendPing(object sharedMemoryConnectionAsObject) { BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; SharedMemoryConnection sharedMemoryConnection = (SharedMemoryConnection)sharedMemoryConnectionAsObject; try { Message message = new Message(this.ITransportContext, sharedMemoryConnection.Remote, GenuineReceivingHandler.PING_MESSAGE_REPLYID, new TransportHeaders(), Stream.Null); message.IsSynchronous = false; message.FinishTime = GenuineUtility.GetTimeout((TimeSpan)message.ITransportContext.IParameterProvider[GenuineParameter.InvocationTimeout]); // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0) { binaryLogWriter.WriteEvent(LogCategory.Connection, "SharedMemoryConnectionManager.SendPing", LogMessageType.ConnectionPingSending, null, message, sharedMemoryConnection.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, sharedMemoryConnection.DbgConnectionId, 0, 0, 0, null, null, null, null, "Ping is being sending."); } message.SerializedContent = Stream.Null; this.SendSync(message, sharedMemoryConnection); } catch (Exception ex) { // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0) { binaryLogWriter.WriteEvent(LogCategory.Connection, "SharedMemoryConnectionManager.SendPing", LogMessageType.ConnectionPingSent, ex, null, sharedMemoryConnection.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, sharedMemoryConnection.DbgConnectionId, 0, 0, 0, null, null, null, null, "Ping cannot be sent."); } } }
/// <summary> /// Constructs an instance of the SecuritySession_Basic class. /// </summary> /// <param name="name">The name of the security context.</param> public SecuritySession_Basic(string name) : base(name, null) { this.IsEstablishedEvent.Set(); // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0) { binaryLogWriter.WriteEvent(LogCategory.Security, "SecuritySession_Basic.SecuritySession_Basic", LogMessageType.SecuritySessionKey, null, null, this.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, this, this.Name, -1, 0, 0, 0, "No security features supported.", null, null, null, "This Security Session does not require establishing."); } }
/// <summary> /// Sets up all security stuff for encrypting content and checking integrity. /// </summary> /// <param name="password">The password.</param> protected void SetupSecurityAlgorithms(string password) { lock (this) { if ((this.ZpaFeatureFlags & ZpaFeatureFlags.ElectronicCodebookEncryption) != 0 || (this.ZpaFeatureFlags & ZpaFeatureFlags.CipherBlockChainingEncryption) != 0) { // encryption this.SymmetricAlgorithm = Rijndael.Create(); this.SymmetricAlgorithm.Key = ZeroProofAuthorizationUtility.GeneratePasswordBasedSequence("Key" + password, this.Salt, 32); this.SymmetricAlgorithm.IV = ZeroProofAuthorizationUtility.GeneratePasswordBasedSequence("IV" + password, this.Salt, 16); this.SymmetricAlgorithm.Mode = (this.ZpaFeatureFlags & ZpaFeatureFlags.ElectronicCodebookEncryption) != 0 ? CipherMode.ECB : CipherMode.CBC; this._encryptor = this.SymmetricAlgorithm.CreateEncryptor(); this._decryptor = this.SymmetricAlgorithm.CreateDecryptor(); } // and integrity checking if ((this.ZpaFeatureFlags & ZpaFeatureFlags.Mac3DesCbcSigning) != 0) { this.KeyedHashAlgorithm = MACTripleDES.Create(); } if ((this.ZpaFeatureFlags & ZpaFeatureFlags.HmacSha1Signing) != 0) { this.KeyedHashAlgorithm = HMACSHA1.Create(); } if (this.KeyedHashAlgorithm != null) { this.KeyedHashAlgorithm.Key = ZeroProofAuthorizationUtility.GeneratePasswordBasedSequence("M3D" + password, this.Salt, 24); } // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0) { binaryLogWriter.WriteEvent(LogCategory.Security, "SecuritySession_BaseZpaSession.SetupSecurityAlgorithms", LogMessageType.SecuritySessionKey, null, null, this.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, this, this.Name, -1, 0, 0, 0, string.Format("Zero Proof Authorization Flags: {0} Encryption: {1} Data Integrity: {2}", Enum.Format(typeof(ZpaFeatureFlags), this.ZpaFeatureFlags, "g"), this.SymmetricAlgorithm == null ? "No" : this.SymmetricAlgorithm.GetType().ToString(), this.KeyedHashAlgorithm == null ? "No" : this.KeyedHashAlgorithm.GetType().ToString()), null, null, null, "Security Session security information is initialized."); } } }
/// <summary> /// Informs all dependent entities that the Security Session has been established. /// </summary> protected virtual void SessionEstablished() { BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0) { binaryLogWriter.WriteEvent(LogCategory.Security, "SecuritySession.SessionEstablished", LogMessageType.SecuritySessionEstablished, null, null, this.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, this, this.Name, -1, 0, 0, 0, null, null, null, null, "Security Session has been established."); } this._isEstablished.Set(); SendAssociatedMessages(); }
/// <summary> /// Initiates establishing Security Session with specific remote host via specified IConnectionManager. /// </summary> /// <param name="securitySessionParameters">Security Session parameters.</param> public void InitiateEstablishingSecuritySession(SecuritySessionParameters securitySessionParameters) { BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0) { binaryLogWriter.WriteEvent(LogCategory.Security, "SecuritySession.InitiateEstablishingSecuritySession", LogMessageType.SecuritySessionInitiated, null, null, this.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, this, this.Name, -1, 0, 0, 0, this.GetType().Name, this.Name, null, null, "Security Session establishing is initiated."); } this.Failed.Reset(); this._establishingSecuritySessionParameters = securitySessionParameters; GenuineThreadPool.QueueUserWorkItem(new WaitCallback(this.Internal_InitiateEstablishingSecuritySession), securitySessionParameters, false); }
/// <summary> /// Exludes the message from the queue. /// </summary> /// <returns>The message or a null reference.</returns> public Message GetMessage() { Message message = null; using (new ReaderAutoLocker(this._disposeLock)) { if (this._disposed) { return(null); } lock (this._queue) { if (this._queue.Count > 0) { message = (Message)this._queue.Dequeue(); } // correct queue total size if (message != null) { this._currentTotalMessages--; this._currentTotalSize -= message.EffectiveMessageSize; // reflect the change in the queue state if (message.Recipient != null) { message.Recipient.QueueLength = this._queue.Count; } // LOG: BinaryLogWriter binaryLogWriter = this._iTransportContext.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0) { binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "MessageContainer.GetMessage", LogMessageType.MessageHasBeenDequeued, null, message, message.Recipient, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, null, null, null, null, "The message has been dequeued. Messages in the queue: {0}. Queue size: {1}.", this._currentTotalMessages, this._currentTotalSize); } } } } return(message); }
/// <summary> /// Releases all resources related to the specified connection. /// </summary> /// <param name="exception">The reason.</param> /// <param name="sharedMemoryConnection">The connection.</param> private void ConnectionFailed(Exception exception, SharedMemoryConnection sharedMemoryConnection) { BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; try { sharedMemoryConnection.IsValid = false; // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0) { binaryLogWriter.WriteEvent(LogCategory.Connection, "SharedMemoryConnectionManager.ConnectionFailed", LogMessageType.ConnectionFailed, exception, null, sharedMemoryConnection.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, sharedMemoryConnection.DbgConnectionId, 0, 0, 0, null, null, null, null, "Connection has failed."); } // unregister the connection if (sharedMemoryConnection.Remote.GenuinePersistentConnectionState == GenuinePersistentConnectionState.Accepted) { this._persistent.Remove(sharedMemoryConnection.Remote.Uri); } else { this._persistent.Remove(sharedMemoryConnection.Remote.Url); } // release all resources this.ITransportContext.KnownHosts.ReleaseHostResources(sharedMemoryConnection.Remote, exception); sharedMemoryConnection.ReleaseUnmanagedResources(); sharedMemoryConnection.SignalState(GenuineEventType.GeneralConnectionClosed, exception, null); } catch (Exception ex) { // LOG: if (binaryLogWriter != null) { binaryLogWriter.WriteImplementationWarningEvent("SharedMemoryConnectionManager.ConnectionFailed", LogMessageType.CriticalError, ex, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, "Unexpected exception inside the SharedMemoryClientConnectionManager.ConnectionFailed method. Most likely, something must be fixed."); } } }
/// <summary> /// Reads messages from the connection and processes them synchronously. /// </summary> public void ReceiveSynchronously() { try { for ( ; ;) { if (!this.SharedMemoryConnection.IsValid) { return; } using (Stream stream = this.SharedMemoryConnection.LowLevel_ReadSync(GenuineUtility.GetTimeout(this.SharedMemoryConnection._closeAfterInactivity))) { // receive the message GenuineChunkedStream theMessage = new GenuineChunkedStream(true); GenuineUtility.CopyStreamToStream(stream, theMessage); // a message was successfully received this.SharedMemoryConnection.Renew(); if (theMessage.Length == 0) { // LOG: BinaryLogWriter binaryLogWriter = this.SharedMemoryConnectionManager.ITransportContext.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0) { binaryLogWriter.WriteEvent(LogCategory.Connection, "SharedMemoryConnectionManager.ReceiveSynchronously", LogMessageType.ConnectionPingReceived, null, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, this.SharedMemoryConnection.DbgConnectionId, 0, 0, 0, null, null, null, null, "A message with zero size is treated as ping."); } continue; } this.SharedMemoryConnectionManager.ITransportContext.IIncomingStreamHandler.HandleMessage(theMessage, this.SharedMemoryConnection.Remote, GenuineConnectionType.Persistent, null, this.SharedMemoryConnection.DbgConnectionId, false, null, this.SharedMemoryConnection.ConnectionLevelSecurity, null); this.SharedMemoryConnection.Renew(); } } } catch (Exception ex) { this.SharedMemoryConnectionManager.ConnectionFailed(ex, this.SharedMemoryConnection); } }
/// <summary> /// Reads data from the socket. /// </summary> /// <param name="buffer">An array of type Byte that is the storage location for received data.</param> /// <param name="offset">The location in buffer to store the received data.</param> /// <param name="count">The number of bytes to receive.</param> /// <returns>The number of bytes read.</returns> public int ReadFromSocket(byte[] buffer, int offset, int count) { BinaryLogWriter binaryLogWriter = this._tcpConnectionManager.ITransportContext.BinaryLogWriter; try { int millisecondsRemained = GenuineUtility.GetMillisecondsLeft(this._receiveTimeout); if (millisecondsRemained <= 0) { throw GenuineExceptions.Get_Send_ServerDidNotReply(); } this._tcpSocketInfo.Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, millisecondsRemained); int bytesReceived = this._tcpSocketInfo.Socket.Receive(buffer, offset, count, SocketFlags.None); // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.LowLevelTransport] > 0) { binaryLogWriter.WriteTransportContentEvent(LogCategory.LowLevelTransport, "SyncSocketReadingStream.ReadFromSocket", LogMessageType.LowLevelTransport_SyncReceivingCompleted, null, null, this._tcpSocketInfo.Remote, binaryLogWriter[LogCategory.LowLevelTransport] > 1 ? new MemoryStream(buffer, offset, bytesReceived) : null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, this._tcpSocketInfo.DbgConnectionId, bytesReceived, this._tcpSocketInfo.Socket.RemoteEndPoint.ToString(), null, null, "Socket.Receive(). Bytes received: {0}.", bytesReceived); } this._tcpConnectionManager.IncreaseBytesReceived(bytesReceived); return(bytesReceived); } catch (Exception ex) { // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.LowLevelTransport] > 0) { binaryLogWriter.WriteEvent(LogCategory.LowLevelTransport, "SyncSocketReadingStream.ReadFromSocket", LogMessageType.LowLevelTransport_SyncReceivingCompleted, ex, null, this._tcpSocketInfo.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, this._tcpSocketInfo.DbgConnectionId, 0, 0, 0, null, null, null, null, "Socket.Receive() failed."); } throw; } }
/// <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> /// 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> /// Stops listening to the specified end point. Does not close any connections. /// </summary> /// <param name="endPoint">The end point</param> public override void StopListening(object endPoint) { BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; if (this._smAcceptConnectionClosure != null) { // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0) { binaryLogWriter.WriteEvent(LogCategory.AcceptingConnection, "SharedMemoryConnectionManager.StopListening", LogMessageType.ListeningStopped, null, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, this._smAcceptConnectionClosure.ShareName, null, null, null, "\"{0}\" is not now listened.", this._smAcceptConnectionClosure.ShareName); } this._smAcceptConnectionClosure.StopListening.Set(); this._smAcceptConnectionClosure = null; } }
/// <summary> /// Initializes an instance of the SecuritySession_KnownSymmetric class. /// </summary> /// <param name="symmetricAlgorithm">The symmetricAlgorithm to be used.</param> /// <param name="name">The name of the security context.</param> public SecuritySession_KnownSymmetric(SymmetricAlgorithm symmetricAlgorithm, string name) : base(name, null) { // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0) { binaryLogWriter.WriteEvent(LogCategory.Security, "SecuritySession_KnownSymmetric.SecuritySession_KnownSymmetric", LogMessageType.SecuritySessionKey, null, null, this.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, this, name, -1, 0, 0, 0, "Encryption using " + symmetricAlgorithm.GetType().ToString(), null, null, null, "Security Session security information is initialized."); } this.SymmetricAlgorithm = symmetricAlgorithm; this._encryptor = this.SymmetricAlgorithm.CreateEncryptor(); this._decryptor = this.SymmetricAlgorithm.CreateDecryptor(); this.IsEstablishedEvent.Set(); }
/// <summary> /// Initiates an asynchronous call to the HTTP handler. /// </summary> /// <param name="context">An HttpContext object that provides references to intrinsic server objects (for example, Request, Response, Session, and Server) used to service HTTP requests.</param> /// <param name="cb">The AsyncCallback to call when the asynchronous method call is complete. If cb is a null reference (Nothing in Visual Basic), the delegate is not called.</param> /// <param name="extraData">Any extra data needed to process the request.</param> /// <returns>An IAsyncResult that contains information about the status of the process.</returns> public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) { try { HttpServerRequestResult httpServerRequestResult = new HttpServerRequestResult(context, cb, extraData); httpServerRequestResult.IPrincipal = Thread.CurrentPrincipal; lock (this._httpServerConnectionManagerLock) if (this._httpServerConnectionManager == null) { GenuineHttpServerChannel serverChannel = ChannelServices.GetChannel("ghttp") as GenuineHttpServerChannel; if (serverChannel == null) { throw GenuineExceptions.Get_Receive_NoServerChannel(); } this._httpServerConnectionManager = serverChannel.ITransportContext.ConnectionManager as HttpServerConnectionManager; } // GenuineThreadPool.QueueUserWorkItem(new WaitCallback(this._httpServerConnectionManager.HandleIncomingRequest), httpServerRequestResult, true); this._httpServerConnectionManager.HandleIncomingRequest(httpServerRequestResult); return(httpServerRequestResult); } catch (Exception ex) { // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.AcceptingConnection] > 0) { binaryLogWriter.WriteEvent(LogCategory.AcceptingConnection, "HttpServerHandler.BeginProcessRequest", LogMessageType.ConnectionAccepting, ex, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, null, null, null, null, "Can't process an incoming connection."); } throw; } }
/// <summary> /// Fires the GenuineChannelsGlobalEvent event with the specified parameters. /// </summary> /// <param name="e">Event arguments.</param> public void FireGenuineEvent(GenuineEventArgs e) { // LOG: BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.ChannelEvent] > 0) { binaryLogWriter.WriteEvent(LogCategory.ChannelEvent, "BasicChannelWithSecurity.FireGenuineEvent", LogMessageType.ChannelEvent, e.SourceException, null, e.HostInformation, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, (int)e.EventType, 0, 0, null, null, null, null, "The channel event is raised."); } if (e.EventType == GenuineEventType.GTcpConnectionAccepted || e.EventType == GenuineEventType.GHttpConnectionAccepted) { this.PerformEventSending(e); } else { GenuineThreadPool.QueueUserWorkItem(new WaitCallback(this.PerformEventSending), e, false); } }
/// <summary> /// Accepts the incoming connection. /// </summary> /// <param name="shareName">The name of the share.</param> /// <param name="protocolVersion">The version of the protocol supported by the remote host.</param> internal void Connection_AcceptConnection(string shareName, byte protocolVersion) { try { // accept the connection string remoteUri = null; int remoteHostUniqueIdentifier; SharedMemoryConnection connection = this.LowLevel_AcceptConnection_1(shareName, this.Local.Uri, protocolVersion, out remoteUri, out remoteHostUniqueIdentifier); connection.Remote = this.ITransportContext.KnownHosts[remoteUri]; connection.Remote.ProtocolVersion = protocolVersion; connection.Remote.GenuinePersistentConnectionState = GenuinePersistentConnectionState.Accepted; connection.Remote.UpdateUri(remoteUri, remoteHostUniqueIdentifier); this._persistent[remoteUri] = connection; connection.SignalState(GenuineEventType.GeneralConnectionEstablished, null, null); // and process incoming messages this.Connection_InitiateReceiving(connection); } catch (Exception ex) { // LOG: BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0) { binaryLogWriter.WriteEvent(LogCategory.Connection, "SharedMemoryConnectionManager.Connection_AcceptConnection", LogMessageType.ConnectionEstablished, ex, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, null, null, null, null, "The connection from the remote host \"{0}\" has been refused.", shareName); } this.ITransportContext.IGenuineEventProvider.Fire(new GenuineEventArgs(GenuineEventType.GeneralListenerFailure, ex, null, shareName)); } }
/// <summary> /// Unregisters unavailable Transport Contexts. /// Does not throw any exceptions. /// </summary> public static void UnregisterUnavailableTransportContexts() { try { ArrayList keysToRemove = new ArrayList(); lock (_knownUris.SyncRoot) { foreach (DictionaryEntry dictionaryEntry in _knownUris) { WeakReference weakReference = dictionaryEntry.Value as WeakReference; if (weakReference == null || !weakReference.IsAlive) { keysToRemove.Add(dictionaryEntry.Key); } } for (int i = 0; i < keysToRemove.Count; i++) { _knownUris.Remove(keysToRemove[i]); } } } catch (Exception ex) { // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0) { binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "UriStorage.UnregisterUnavailableTransportContexts", LogMessageType.Error, ex, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, null, null, null, null, "Unexpected exception occurred while unregistering unavailable transport contexts."); } } }
/// <summary> /// Destroys the Security Session with the specified name. /// Releases all Security Session resources. /// </summary> /// <param name="securitySessionName">The name of the Security Session.</param> public void DestroySecuritySession(string securitySessionName) { lock (this.DisposeLock) { if (this.IsDisposed) { throw OperationException.WrapException(this.DisposeReason); } lock (_securitySessions) { SecuritySession iSecuritySession = _securitySessions[securitySessionName] as SecuritySession; if (iSecuritySession != null) { IDisposable iDisposable = iSecuritySession as IDisposable; if (iDisposable != null) { iDisposable.Dispose(); } // LOG: BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0) { binaryLogWriter.WriteEvent(LogCategory.Security, "HostInformation.DestroySecuritySession", LogMessageType.SecuritySessionDestroyed, null, null, iSecuritySession.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, iSecuritySession, iSecuritySession.Name, -1, 0, 0, 0, iSecuritySession.GetType().Name, iSecuritySession.Name, null, null, "Security Session has been destroyed manually."); } _securitySessions.Remove(securitySessionName); } } } }
/// <summary> /// Services the work items. /// </summary> public static void ServiceWorkItems() { for ( ; ;) { _manualResetEvent.WaitOne(); lock (_workItems.SyncRoot) { for (int i = 0; i < _workItems.Count; i++) { IAsyncWorkItem iAsyncWorkItem = (IAsyncWorkItem)_workItems[i]; try { iAsyncWorkItem.StartAsynchronousOperation(); } catch (Exception ex) { // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null) { binaryLogWriter.WriteEvent(LogCategory.ImplementationWarning, "AsyncThreadStarter.ServiceWorkItems", LogMessageType.Error, ex, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, null, null, null, null, "Execution of \"{0}\" workitem has resulted in exception.", iAsyncWorkItem.GetType().FullName); } } } _workItems.Clear(); _manualResetEvent.Reset(); } } }
/// <summary> /// Increases all queue counters according to the provided message and /// puts a message into the queue. /// </summary> /// <param name="message">The message being put into the queue.</param> /// <param name="onlyCheckIn">Check the message in without adding it to any queues.</param> public void AddMessage(Message message, bool onlyCheckIn) { BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; using (new ReaderAutoLocker(this._disposeLock)) { if (this._disposed) { throw OperationException.WrapException(this._disposeException); } int maxContentSize = 0; if (message.SecuritySessionParameters != null) { maxContentSize = message.SecuritySessionParameters.MaxContentSize; } if (maxContentSize == 0) { maxContentSize = this._maxContentSize; } if (maxContentSize > 0 && !this._noSizeChecking) { // calculate message effective size try { if (message.SerializedContent != null && message.SerializedContent.CanSeek) { message.EffectiveMessageSize = (int)message.SerializedContent.Length; } // else if (message.Stream != null && message.Stream.CanSeek) // message.EffectiveMessageSize = (int) message.Stream.Length; } catch (Exception ex) { // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.ImplementationWarning] > 0) { binaryLogWriter.WriteEvent(LogCategory.ImplementationWarning, "MessageContainer.AddMessage", LogMessageType.Warning, ex, message, message.Recipient, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, null, null, null, null, "Message stream doesn't support the Length property. Set the NoSizeChecking parameter to true to increase performance"); } } try { if (message.SerializedContent != null && message.EffectiveMessageSize == 0 && message.SerializedContent.CanSeek) { message.EffectiveMessageSize = Math.Min(message.EffectiveMessageSize, (int)message.SerializedContent.Length); } } catch (Exception ex) { // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.ImplementationWarning] > 0) { binaryLogWriter.WriteEvent(LogCategory.ImplementationWarning, "MessageContainer.AddMessage", LogMessageType.Warning, ex, message, message.Recipient, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, null, null, null, null, "Message stream doesn't support the Length property. Set the NoSizeChecking parameter to true to increase performance"); } } // check the message size if (message.EffectiveMessageSize > maxContentSize) { throw GenuineExceptions.Get_Send_TooLargePacketSize((int)message.EffectiveMessageSize, maxContentSize); } } bool overloaded = false; lock (this._queue) { // check on total size if (this._currentTotalMessages + 1 > this._maxQueuedItems || message.EffectiveMessageSize + this._currentTotalSize > this._maxTotalSize) { // to prevent a deadlock overloaded = true; } else { this._currentTotalMessages++; this._currentTotalSize += message.EffectiveMessageSize; // put it into the queue or awaiting list if (!onlyCheckIn) { this._queue.Enqueue(message); // reflect the change in the queue state if (message.Recipient != null) { message.Recipient.QueueLength = this._queue.Count; } // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0) { binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "MessageContainer.AddMessage", LogMessageType.MessageIsEnqueued, null, message, message.Recipient, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, null, null, null, null, "The message has been enqueued because no connections are available. Messages in the queue: {0}. Queue size: {1}.", this._currentTotalMessages, this._currentTotalSize); } } } } // lock (this._queue) if (overloaded) { Exception exception = GenuineExceptions.Get_Send_QueueIsOverloaded(this._maxQueuedItems, this._currentTotalMessages + 1, this._maxTotalSize, message.EffectiveMessageSize + this._currentTotalSize); // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0) { binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "MessageContainer.AddMessage", LogMessageType.MessageIsEnqueued, exception, message, message.Recipient, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, null, null, null, null, "Queue is overrun."); } this.Dispose(exception); throw exception; } } }