Пример #1
0
        /// <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);
                }
            }
        }
Пример #4
0
        /// <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);
                }
            }
        }
Пример #5
0
        /// <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();
                }
            }
        }
Пример #6
0
        /// <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);
        }
Пример #7
0
        /// <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();
        }
Пример #8
0
        /// <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();
        }
Пример #9
0
        /// <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.");
            }
        }
Пример #10
0
        /// <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.");
                }
            }
        }
Пример #14
0
        /// <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();
        }
Пример #15
0
        /// <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);
        }
Пример #16
0
        /// <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;
            }
        }
Пример #20
0
        /// <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();
        }
Пример #24
0
        /// <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));
            }
        }
Пример #27
0
        /// <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.");
                }
            }
        }
Пример #28
0
        /// <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);
                    }
                }
            }
        }
Пример #29
0
        /// <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();
                }
            }
        }
Пример #30
0
        /// <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;
                }
            }
        }