コード例 #1
0
//		/// <summary>
//		/// The time when the listening request was received.
//		/// </summary>
//		public int Listener_Opened;

        #endregion

        #region -- Disposing -----------------------------------------------------------------------

        /// <summary>
        /// Releases resources.
        /// </summary>
        /// <param name="reason">The reason of disposing.</param>
        public override void InternalDispose(Exception reason)
        {
            if (this.Socket != null)
            {
                GenuineThreadPool.QueueUserWorkItem(new WaitCallback(SocketUtility.CloseSocket), this.Socket, true);
                this.Socket = null;
            }

            lock (this.PhysicalConnectionStateLock)
            {
                if (this.SentContent != null)
                {
                    this.SentContent.Close();
                    this.SentContent = null;
                }

                if (this.MessagesBeingSent != null)
                {
                    foreach (Message message in this.MessagesBeingSent)
                    {
                        this.XHttpConnection.ITransportContext.IIncomingStreamHandler.DispatchException(message, reason);
                    }
                }
                this.MessagesBeingSent.Clear();
            }
        }
コード例 #2
0
        /// <summary>
        /// Fires the event.
        /// </summary>
        /// <param name="genuineEventArgs">The event parameters.</param>
        public void Fire(GenuineEventArgs genuineEventArgs)
        {
            // acquire read access and get a list of the event receivers
            object[] handlers;
            using (new ReaderAutoLocker(this._handlersLock))
                handlers = this._handlers.ToArray();

            foreach (IGenuineEventHandler iGenuineEventHandler in handlers)
            {
                try
                {
                    iGenuineEventHandler.OnGenuineEvent(genuineEventArgs);
                }
                catch (Exception)
                {
                    using (new WriterAutoLocker(this._handlersLock))
                        this._handlers.Remove(iGenuineEventHandler);
                }
            }

            // fire the global event as well
            if (genuineEventArgs.EventType == GenuineEventType.GTcpConnectionAccepted)
            {
                this.FireGlobalEvent(genuineEventArgs);
            }
            else
            {
                GenuineThreadPool.QueueUserWorkItem(new WaitCallback(this.FireGlobalEvent), genuineEventArgs, false);
            }
        }
コード例 #3
0
 /// <summary>
 /// Closes the socket.
 /// </summary>
 public void CloseSocket()
 {
     lock (this._accessToLocalMembers)
     {
         GenuineThreadPool.QueueUserWorkItem(new WaitCallback(SocketUtility.CloseSocket), this.Socket, false);
         this.Socket = null;
     }
 }
コード例 #4
0
        /// <summary>
        /// Creates and returns a stream containing decrypted data.
        /// </summary>
        /// <param name="input">A stream containing encrypted data.</param>
        /// <returns>A stream with decrypted data.</returns>
        public override Stream Decrypt(Stream input)
        {
            // check on view whether it's session's packet
            if (input.ReadByte() == 0)
            {
                // continue the Security Session establishing
                Stream outputStream = this.EstablishSession(input, false);

                if (outputStream != null)
                {
                    GenuineThreadPool.QueueUserWorkItem(new WaitCallback(this.SendMessage), outputStream, false);
                }
                return(null);
            }

            lock (this)
            {
                GenuineChunkedStream output = new GenuineChunkedStream(false);
                byte[] sign = null;

                int signSize = 0;
                if (this.KeyedHashAlgorithm != null)
                {
                    signSize = this.KeyedHashAlgorithm.HashSize / 8;
                }

                // decrypt the content and fetch the sign
                if (this._decryptor != null)
                {
                    CryptoStream cryptoStream = new CryptoStream(new FinishReadingStream(output), this._decryptor, CryptoStreamMode.Write);
                    sign = GenuineUtility.CopyStreamToStreamExceptSign(input, cryptoStream, signSize);
                    cryptoStream.FlushFinalBlock();
                }
                else
                {
                    sign = GenuineUtility.CopyStreamToStreamExceptSign(input, output, signSize);
                }

                // check the sign
                if (this.KeyedHashAlgorithm != null)
                {
                    if (!ZeroProofAuthorizationUtility.CompareBuffers(sign, this.KeyedHashAlgorithm.ComputeHash(output), sign.Length))
                    {
                        throw GenuineExceptions.Get_Security_WrongSignature();
                    }
                    output.Position = 0;
                }

                output.ReleaseOnReadMode = true;
                return(output);
            }
        }
コード例 #5
0
        /// <summary>
        /// Creates and returns a stream containing decrypted data.
        /// </summary>
        /// <param name="input">A stream containing encrypted data.</param>
        /// <returns>A stream with decrypted data.</returns>
        public override Stream Decrypt(Stream input)
        {
            if (input.ReadByte() == 0)
            {
                Stream outputStream = this.EstablishSession(input, false);
                if (outputStream != null)
                {
                    GenuineThreadPool.QueueUserWorkItem(new WaitCallback(this.SendMessage), outputStream, false);
                }
                return(null);
            }

            return(this.SspiSecurityContext.DecryptMessage(input, this.KeyProvider_SspiServer.RequiredFeatures));
        }
コード例 #6
0
        /// <summary>
        /// Removes all recipients and broadcast senders.
        /// </summary>
        public void Clear()
        {
            using (WriterAutoLocker writer = new WriterAutoLocker(this._readerWriterLock))
            {
                this._cachedReceiversInfoArray = null;

                // collect all receivers to unregister the sponsor
                object[] receiverInfoItems = new object[this._receivers.Count];
                this._receivers.Values.CopyTo(receiverInfoItems, 0);
                GenuineThreadPool.QueueUserWorkItem(new WaitCallback(this.UnregisterSponsor), receiverInfoItems, true);

                this._receivers.Clear();
            }
        }
コード例 #7
0
 /// <summary>
 /// Closes the socket.
 /// </summary>
 public void Dispose()
 {
     try
     {
         lock (this._syncRoot)
         {
             if (this.socket != null)
             {
                 GenuineThreadPool.QueueUserWorkItem(new WaitCallback(SocketUtility.CloseSocket), this.socket, true);
                 this.socket = null;
             }
         }
     }
     catch
     {
     }
 }
コード例 #8
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);
        }
コード例 #9
0
        /// <summary>
        /// Closes expired connections and sends ping via inactive connections.
        /// </summary>
        public void TimerCallback()
        {
            int now            = GenuineUtility.TickCount;
            int forcePingAfter = GenuineUtility.ConvertToMilliseconds(this.ITransportContext.IParameterProvider[GenuineParameter.PersistentConnectionSendPingAfterInactivity]);

            lock (this._persistent.SyncRoot)
            {
                // by all connections
                foreach (DictionaryEntry dictionaryEntry in this._persistent)
                {
                    SharedMemoryConnection sharedMemoryConnection = (SharedMemoryConnection)dictionaryEntry.Value;
                    if (GenuineUtility.IsTimeoutExpired(sharedMemoryConnection.LastTimeAMessageWasSent + forcePingAfter, now))
                    {
                        GenuineThreadPool.QueueUserWorkItem(new WaitCallback(this.SendPing), sharedMemoryConnection, false);
                    }
                }
            }
        }
コード例 #10
0
        /// <summary>
        /// Creates and returns a stream containing decrypted data.
        /// </summary>
        /// <param name="input">A stream containing encrypted data.</param>
        /// <returns>A stream with decrypted data.</returns>
        public override Stream Decrypt(Stream input)
        {
            // check on view whether it's session's packet
            if (input.ReadByte() == 0)
            {
                // continue the Security Session establishing
                Stream outputStream = this.EstablishSession(input, false);

                if (outputStream != null)
                {
                    GenuineThreadPool.QueueUserWorkItem(new WaitCallback(this.SendMessage), outputStream, false);
                }
                return(null);
            }

            if (this.RijndaelKey == null)
            {
                throw GenuineExceptions.Get_Security_ContextWasNotEstablished(this.Name);
            }

            lock (this.RijndaelKey)
            {
                if (this._decryptor == null)
                {
                    Rijndael rijndael = Rijndael.Create();
                    rijndael.Key  = this.RijndaelKey;
                    rijndael.Mode = CipherMode.ECB;

                    this._encryptor = rijndael.CreateEncryptor();
                    this._decryptor = rijndael.CreateDecryptor();
                }
            }

            lock (this._decryptor)
            {
                GenuineChunkedStream output = new GenuineChunkedStream(true);
                GenuineUtility.CopyStreamToStream(new CryptoStream(new FinishReadingStream(input), this._decryptor, CryptoStreamMode.Read), output);

                GenuineUtility.CopyStreamToStream(input, Stream.Null);
                input.Close();

                return(output);
            }
        }
コード例 #11
0
        /// <summary>
        /// Removes the receiver or the broadcast sender associated with the specified uri.
        /// Returns false if there is no such receiver found in the list of receivers.
        /// </summary>
        /// <param name="uri">The uri of the receiver.</param>
        public bool Remove(string uri)
        {
            if (uri == null || uri.Length <= 0)
            {
                return(false);
            }

            using (WriterAutoLocker writer = new WriterAutoLocker(this._readerWriterLock))
            {
                // check if it is in the list
                if (!this._receivers.ContainsKey(uri))
                {
                    return(false);
                }

                this._cachedReceiversInfoArray = null;

                ReceiverInfo receiverInfo = (ReceiverInfo)this._receivers[uri];
                this._receivers.Remove(uri);

                // LOG:
                BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter;
                if (binaryLogWriter != null && binaryLogWriter[LogCategory.BroadcastEngine] > 0)
                {
                    binaryLogWriter.WriteBroadcastEngineEvent(LogCategory.BroadcastEngine, "Dispatcher.Remove",
                                                              LogMessageType.BroadcastRecipientRemoved, null, null, receiverInfo.DbgRemoteHost, null,
                                                              GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                              null, null, false, this, null, true, receiverInfo,
                                                              uri, null,
                                                              "The broadcast recipient or \"true\" broadcast sender is removed from the list of recipients.");
                }

                // Sponsor is being deleted in another thread; otherwise client disconnection
                // will cause dispatcher to be freezed for lengthy time out
                GenuineThreadPool.QueueUserWorkItem(new WaitCallback(this.DeleteSponsorFromTheObjectAndFireEvent), receiverInfo, false);
            }

            return(true);
        }
コード例 #12
0
        /// <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);
            }
        }
コード例 #13
0
        /// <summary>
        /// Releases expired host structures.
        /// </summary>
        public void TimerCallback()
        {
            int             now             = GenuineUtility.TickCount;
            HostInformation hostInformation = null;

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

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

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

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

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

                        i++;
                    }
                }

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

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

                    GenuineThreadPool.QueueUserWorkItem(new WaitCallback(this.ReleaseHostResources), new HostInformationAndReason(hostInformationExcluded, GenuineExceptions.Get_Channel_ClientDidNotReconnectWithinTimeOut(hostInformationExcluded.ToString())), true);
                }
            }
        }
コード例 #14
0
        /// <summary>
        /// Accepts incoming connections.
        /// </summary>
        public void AcceptConnections()
        {
            BinaryLogWriter       binaryLogWriter = this.ITransportContext.BinaryLogWriter;
            byte                  protocolVersion;
            GenuineConnectionType genuineConnectionType;

            try
            {
                IParameterProvider parameters = this.ITransportContext.IParameterProvider;

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

                this._mutex = WindowsAPI.CreateMutex(mutexName);

                this._clientConnectedEvent = NamedEvent.CreateNamedEvent(clientConnected, false, false);
                this._clientAcceptedEvent  = NamedEvent.CreateNamedEvent(clientAccepted, false, true);
                WaitHandle[] handles = new WaitHandle[2] {
                    this._clientConnectedEvent.ManualResetEvent, this.StopListening
                };

                for ( ; ;)
                {
                    try
                    {
                        // listen
                        WaitHandle.WaitAny(handles);

                        // if shutting down
                        if (this.StopListening.WaitOne(0, false))
                        {
                            return;
                        }

                        // set timeout
                        int timeout = GenuineUtility.GetTimeout((TimeSpan)this.ITransportContext.IParameterProvider[GenuineParameter.ConnectTimeout]);

                        // client is connecting
                        using (Stream headerStream = this.SharedMemoryConnection.LowLevel_ReadSync(timeout))
                        {
                            BinaryReader binaryReader = new BinaryReader(headerStream);
                            string       connectionId;
                            MessageCoder.DeserializeConnectionHeader(binaryReader, out protocolVersion, out genuineConnectionType, out connectionId);
                            string shareName = binaryReader.ReadString();
                            this._clientAcceptedEvent.ManualResetEvent.Set();

                            // LOG:
                            if (binaryLogWriter != null && binaryLogWriter[LogCategory.AcceptingConnection] > 0)
                            {
                                binaryLogWriter.WriteEvent(LogCategory.AcceptingConnection, "SMAcceptConnectionClosure.AcceptConnections",
                                                           LogMessageType.ConnectionAccepting, null, null, null, null,
                                                           GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                           null, null, -1, 0, 0, 0, null, null, null, null,
                                                           "An inbound Shared Memory connection is being accepted.");
                            }

                            AcceptConnectionInformation acceptConnectionInformation = new AcceptConnectionInformation();
                            acceptConnectionInformation.ShareName       = shareName;
                            acceptConnectionInformation.ProtocolVersion = protocolVersion;
                            GenuineThreadPool.QueueUserWorkItem(new WaitCallback(this.AcceptConnection), acceptConnectionInformation, true);
                        }
                    }
                    catch (Exception ex)
                    {
                        // LOG:
                        if (binaryLogWriter != null && binaryLogWriter[LogCategory.AcceptingConnection] > 0)
                        {
                            binaryLogWriter.WriteEvent(LogCategory.AcceptingConnection, "SMAcceptConnectionClosure.AcceptConnections",
                                                       LogMessageType.ConnectionAccepting, ex, null, null, null,
                                                       GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                       null, null, -1, 0, 0, 0, null, null, null, null,
                                                       "Can't accept a connection.");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                // LOG:
                if (binaryLogWriter != null && binaryLogWriter[LogCategory.AcceptingConnection] > 0)
                {
                    binaryLogWriter.WriteEvent(LogCategory.AcceptingConnection, "SMAcceptConnectionClosure.AcceptConnections",
                                               LogMessageType.CriticalError, ex, null, null, null,
                                               GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                               null, null, -1, 0, 0, 0, null, null, null, null,
                                               "Critical listener failure. No connections will be accepted.");
                }

                this.SharedMemoryConnectionManager.ITransportContext.IGenuineEventProvider.Fire(new GenuineEventArgs(GenuineEventType.GeneralListenerFailure, ex, null, this.ShareName));
            }
            finally
            {
                this.SharedMemoryConnection.ReleaseUnmanagedResources();
                if (this._mutex != null)
                {
                    this._mutex.Close();
                }
            }
        }
コード例 #15
0
        /// <summary>
        /// Sends the invocation to all registered receivers.
        /// </summary>
        /// <param name="msg">The message to be sent.</param>
        public void PerformBroadcasting(IMessage msg)
        {
            BinaryLogWriter binaryLogWriter  = GenuineLoggingServices.BinaryLogWriter;
            string          methodName       = null;
            string          invocationTarget = null;

            // the first stage of the broadcasting
            try
            {
                ArrayList listOfExcludedReceivers = new ArrayList();
                this._iMessage = msg;
                methodName     = BinaryLogWriter.ParseInvocationMethod(msg.Properties["__MethodName"] as string, msg.Properties["__TypeName"] as string);

                BinaryFormatter formatterForLocalRecipients = null;

                // serialize the message
                BinaryFormatter binaryFormatter = new BinaryFormatter(new RemotingSurrogateSelector(), new StreamingContext(StreamingContextStates.Other));
                this._messageStream = new GenuineChunkedStream(false);
                binaryFormatter.Serialize(this._messageStream, msg);

                // to trace the message if it could reach the server via several channels
                string callGuidSubstring = null;
                if (this._dispatcher.IgnoreRecurrentCalls)
                {
                    callGuidSubstring = Guid.NewGuid().ToString("N");
                }

                // LOG:
                if (binaryLogWriter != null && binaryLogWriter[LogCategory.BroadcastEngine] > 0)
                {
                    binaryLogWriter.WriteBroadcastEngineEvent(LogCategory.BroadcastEngine, "ResultCollector.PerformBroadcasting",
                                                              LogMessageType.BroadcastInvocationInitiated, null, null, null,
                                                              binaryLogWriter[LogCategory.BroadcastEngine] > 1 ? (Stream)this._messageStream.Clone() : null,
                                                              GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                              null, null, true, this._dispatcher, this, false, null,
                                                              methodName, null,
                                                              "The broadcast invocation is initiated.");
                }

                // to prevent firing resultCollector.AllMessagesReceived event
                this.UnrepliedReceivers[_uniqueReceiverName] = null;

                object[] listOfReceiverInfo;
                this._dispatcher.GetListOfReceivers(out listOfReceiverInfo, msg, this);

                // through all recipients
                for (int i = 0; i < listOfReceiverInfo.Length; i++)
                {
                    ReceiverInfo receiverInfo = listOfReceiverInfo[i] as ReceiverInfo;
                    if (receiverInfo == null)
                    {
                        continue;
                    }

                    string mbrUri = (string)receiverInfo.MbrUri;
                    invocationTarget = mbrUri;

                    try
                    {
                        lock (receiverInfo)
                        {
                            if (this._dispatcher.MaximumNumberOfConsecutiveFailsToExcludeReceiverAutomatically != 0 &&
                                receiverInfo.NumberOfFails >= this._dispatcher.MaximumNumberOfConsecutiveFailsToExcludeReceiverAutomatically)
                            {
                                // put it to the list containing receivers being excluded
                                listOfExcludedReceivers.Add(mbrUri);
                                continue;
                            }
                        }

                        // think that it'll fail
                        if (!receiverInfo.Local && receiverInfo.GeneralBroadcastSender == null)
                        {
                            lock (this)
                            {
                                this.Failed[mbrUri] = GenuineExceptions.Get_Broadcast_RemoteEndPointDidNotReplyForTimeOut();
                            }
                        }

                        if (receiverInfo.Local)
                        {
                            // call to local appdomain
                            // ignore recurrent calls
                            if (this._dispatcher.IgnoreRecurrentCalls && UniqueCallTracer.Instance.WasGuidRegistered(mbrUri + callGuidSubstring))
                            {
                                continue;
                            }

                            // we'll wait for the answer from this receiver
                            this.UnrepliedReceivers[mbrUri] = null;

                            // LOG:
                            if (binaryLogWriter != null && binaryLogWriter[LogCategory.BroadcastEngine] > 0)
                            {
                                binaryLogWriter.WriteBroadcastEngineEvent(LogCategory.BroadcastEngine, "ResultCollector.PerformBroadcasting",
                                                                          LogMessageType.BroadcastRecipientInvoked, null, null, null, null,
                                                                          GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                                          null, null, false, this._dispatcher, this, false, receiverInfo,
                                                                          null, null,
                                                                          "The local receiver is invoked via LocalPerformer.");
                            }

                            if (formatterForLocalRecipients == null)
                            {
                                formatterForLocalRecipients = new BinaryFormatter();
                            }

                            // fixed in 2.5.9.6
                            IMessage iLocalMessage = (IMessage)formatterForLocalRecipients.Deserialize((Stream)this._messageStream.Clone());

                            // queue task to run the call locally
                            //IMessage iLocalMessage = (IMessage) binaryFormatter.Deserialize( (Stream) this._messageStream.Clone() );
                            LocalPerformer localPerformer = new LocalPerformer(iLocalMessage, this, receiverInfo.MbrObject);
                            GenuineThreadPool.QueueUserWorkItem(new WaitCallback(localPerformer.Call), null, false);
                        }
                        else if (receiverInfo.GeneralBroadcastSender != null)
                        {
                            // call via true multicast channel
                            Stream messageToBeSent = (Stream)this._messageStream.Clone();

                            // send via real broadcast sender to the specific court
                            msg.Properties["__Uri"] = string.Empty;
                            Message message = Message.CreateOutcomingMessage(receiverInfo.GeneralBroadcastSender.ITransportContext, msg, new TransportHeaders(), messageToBeSent, false);
                            message.DestinationMarshalByRef = receiverInfo.SerializedObjRef;
                            message.GenuineMessageType      = GenuineMessageType.TrueBroadcast;

                            // to ignore recurrent calls on the remote side
                            if (this._dispatcher.IgnoreRecurrentCalls)
                            {
                                message.ITransportHeaders[Message.TransportHeadersBroadcastSendGuid] = callGuidSubstring;
                            }

                            // LOG:
                            if (binaryLogWriter != null && binaryLogWriter[LogCategory.BroadcastEngine] > 0)
                            {
                                message.ITransportHeaders[Message.TransportHeadersInvocationTarget] = invocationTarget;
                                message.ITransportHeaders[Message.TransportHeadersMethodName]       = methodName;

                                binaryLogWriter.WriteBroadcastEngineEvent(LogCategory.BroadcastEngine, "ResultCollector.PerformBroadcasting",
                                                                          LogMessageType.BroadcastRecipientInvoked, null, null, null, null,
                                                                          GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                                          null, null, false, this._dispatcher, this, false, receiverInfo,
                                                                          null, null,
                                                                          "Mulsticast sender is being invoked.");
                            }

                            // register to catch all the answers
                            receiverInfo.GeneralBroadcastSender.ITransportContext.IIncomingStreamHandler.RegisterResponseProcessor(message.MessageId, this);
                            // and send it
                            receiverInfo.GeneralBroadcastSender.SendMessage(message, this);
                        }
                        else
                        {
                            // send the invocation through the usual channel
                            // we'll wait for the reply
                            this.UnrepliedReceivers[mbrUri] = null;

                            // send only if this receiver is not expected to receive message via broadcast channel
                            if (receiverInfo.NeedsBroadcastSimulation)
                            {
                                // each time a new stream is created because sinks change stream position concurrently
                                Stream           messageToBeSent  = (Stream)this._messageStream.Clone();
                                TransportHeaders transportHeaders = new TransportHeaders();

                                // to ignore recurrent calls on the remote side
                                if (this._dispatcher.IgnoreRecurrentCalls)
                                {
                                    transportHeaders[Message.TransportHeadersBroadcastSendGuid] = callGuidSubstring;
                                }

                                // LOG:
                                if (binaryLogWriter != null && binaryLogWriter[LogCategory.BroadcastEngine] > 0)
                                {
                                    binaryLogWriter.WriteBroadcastEngineEvent(LogCategory.BroadcastEngine, "ResultCollector.PerformBroadcasting",
                                                                              LogMessageType.BroadcastRecipientInvoked, null, null, receiverInfo.DbgRemoteHost, null,
                                                                              GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                                              null, null, false, this._dispatcher, this, false, receiverInfo,
                                                                              null, null,
                                                                              "The broadcast recipient is being invoked directly.");
                                }

                                // invoke the destination MBR
                                msg.Properties["__Uri"] = receiverInfo.MbrUri;
                                transportHeaders[Message.TransportHeadersBroadcastObjRefOrCourt] = receiverInfo.SerializedObjRef;
                                transportHeaders[Message.TransportHeadersMbrUriName]             = receiverInfo.MbrUri;
                                transportHeaders[Message.TransportHeadersGenuineMessageType]     = GenuineMessageType.BroadcastEngine;
                                transportHeaders[Message.TransportHeadersInvocationTarget]       = invocationTarget;
                                transportHeaders[Message.TransportHeadersMethodName]             = methodName;
                                ClientChannelSinkStack clientChannelSinkStack = new ClientChannelSinkStack(this);
                                clientChannelSinkStack.Push(this, null);
                                receiverInfo.IClientChannelSink.AsyncProcessRequest(clientChannelSinkStack, this._iMessage, transportHeaders, messageToBeSent);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        this.ParseResult(mbrUri, null, ex);
                    }
                }

                // remove set uri from the hash to check wither the invocation finished
                this.UnrepliedReceivers.Remove(_uniqueReceiverName);
                if (this.UnrepliedReceivers.Count <= 0)
                {
                    this.AllMessagesReceived.Set();
                }

                this.StartReceiving();

                if (listOfExcludedReceivers.Count > 0)
                {
                    foreach (string uri in listOfExcludedReceivers)
                    {
                        this._dispatcher.Remove(uri);
                    }
                }
            }
            catch (Exception ex)
            {
                // LOG:
                if (binaryLogWriter != null && binaryLogWriter[LogCategory.BroadcastEngine] > 0)
                {
                    binaryLogWriter.WriteBroadcastEngineEvent(LogCategory.BroadcastEngine, "ResultCollector.PerformBroadcasting",
                                                              LogMessageType.BroadcastInvocationInitiated, ex, null, null, null,
                                                              GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                              null, null, false, this._dispatcher, this, false, null,
                                                              invocationTarget, methodName,
                                                              "A critical failure occurred during broadcast.");
                }

                throw;
            }
        }
コード例 #16
0
 /// <summary>
 /// Starts connection establishing.
 /// </summary>
 public void StartOperation()
 {
     GenuineThreadPool.QueueUserWorkItem(new WaitCallback(this.StartConnecting), null, true);
 }
コード例 #17
0
        /// <summary>
        /// Accepts incoming connections.
        /// </summary>
        public void AcceptConnections()
        {
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;
            Exception       exception       = null;
            int             numberOfFailure = 0;

            try
            {
                for ( ; ;)
                {
                    try
                    {
                        if (this.IAcceptConnectionConsumer.IsDisposed())
                        {
                            return;
                        }
                        if (this.StopListening.WaitOne(0, false))
                        {
                            return;
                        }

                        Socket clientSocket = this.Socket.Accept();
                        GenuineThreadPool.QueueUserWorkItem(new WaitCallback(this.AcceptConnection), clientSocket, true);
                    }
                    catch (Exception ex)
                    {
                        numberOfFailure++;

                        // LOG:
                        if (binaryLogWriter != null && binaryLogWriter[LogCategory.AcceptingConnection] > 0)
                        {
                            binaryLogWriter.WriteEvent(LogCategory.AcceptingConnection, "GenuineTcp.AcceptConnectionClosure.AcceptConnections",
                                                       LogMessageType.ConnectionAccepting, ex, null, null, null,
                                                       GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                       null, null, -1, 0, 0, 0, null, null, null, null,
                                                       "An inbound TCP connection has not been accepted. Number of failure: {0}.", numberOfFailure);
                        }

                        this.ITransportContext.IGenuineEventProvider.Fire(new GenuineEventArgs(GenuineEventType.GeneralListenerFailure, ex, null, ListeningEndPoint));
                    }
                }
            }
            catch (Exception ex)
            {
                exception = ex;

                // LOG:
                if (binaryLogWriter != null && binaryLogWriter[LogCategory.AcceptingConnection] > 0)
                {
                    binaryLogWriter.WriteEvent(LogCategory.AcceptingConnection, "GenuineTcp.AcceptConnectionClosure.AcceptConnections",
                                               LogMessageType.ListeningStopped, ex, null, null, null,
                                               GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                               null, null, -1, 0, 0, 0, null, null, null, null,
                                               "Fatal Error. The socket does not accept inbound connections any longer.");
                }

                this.ITransportContext.IGenuineEventProvider.Fire(new GenuineEventArgs(GenuineEventType.GeneralListenerFailure, ex, null, this.ListeningEndPoint));
            }
            finally
            {
                SocketUtility.CloseSocket(this.Socket);
            }
        }