public void CreatedWithEmptyName()
        {
            MessageCoder coder = new MessageCoder();

            Assert.NotNull(coder);
            Assert.Equal(string.Empty, coder.Name);
        }
示例#2
0
        public bool Send(int cmd, string message)
        {
            bool ret = false;

            if (_Socket == null)
            {
                LogHelper.Error("发送信息失败!连接已经断开");
                return(ret);
            }

            CMD_BASE_MESSAGE rep = new CMD_BASE_MESSAGE();

            rep.Cmd     = cmd;
            rep.Message = message;

            MemoryStream ms = MessageTransformation.Serialize <CMD_BASE_MESSAGE>(rep);

            byte[] entityData = ms.ToArray();

            byte[] messagedate = MessageCoder.MessageEncoding(entityData);

            //_Socket.Send(messagedate);

            SendAsync(messagedate, 0, messagedate.Length);

            ret = true;

            return(ret);
        }
        public void NameRemainsSet()
        {
            MessageCoder coder = new MessageCoder();

            coder.Name = nameToTest;

            Assert.Equal(nameToTest, coder.Name);
        }
        public void DecodeWithInvalidName()
        {
            MessageCoder coder = new MessageCoder();

            bool result = coder.Decode(invalidEncodedResult);

            Assert.False(result);
        }
        public void DecodeWithValidName()
        {
            MessageCoder coder = new MessageCoder();

            bool result = coder.Decode(validEncodedResult);

            Assert.True(result);
            Assert.Equal(nameToTest, coder.Name);
        }
        public static async Task BroadcastAsync(TcpClient[] clients, IMessageProtocol messageProtocol)
        {
            var bytes = MessageCoder.Encode(messageProtocol);

            foreach (var client in clients)
            {
                await WriteAsync(client, bytes);
            }
        }
        public void EncodeWithValidName()
        {
            MessageCoder coder = new MessageCoder();

            coder.Name = nameToTest;

            string result = coder.Encode();

            Assert.Equal(validEncodedResult, result);
        }
        public void EncodeWithInvalidName()
        {
            MessageCoder coder = new MessageCoder();

            coder.Name = string.Empty;

            string result = coder.Encode();

            Assert.Equal(invalidEncodedResult, result);
        }
        /// <summary>
        /// Sends the stream to the remote host.
        /// </summary>
        /// <param name="message">The message.</param>
        public void SendMessage(Message message)
        {
            int            availableConnectionEntry = 0;
            HttpWebRequest httpWebRequest           = null;

            try
            {
                // serialize the message
                GenuineChunkedStream stream = new GenuineChunkedStream(false);
                using (BufferKeeper bufferKeeper = new BufferKeeper(0))
                {
                    MessageCoder.FillInLabelledStream(message, null, null, stream, bufferKeeper.Buffer,
                                                      (int)this.ITransportContext.IParameterProvider[GenuineParameter.HttpRecommendedPacketSize]);
                }

                // add the header
                GenuineChunkedStream resultStream = new GenuineChunkedStream(false);
                BinaryWriter         binaryWriter = new BinaryWriter(resultStream);
                HttpMessageCoder.WriteRequestHeader(binaryWriter, MessageCoder.PROTOCOL_VERSION, GenuineConnectionType.Invocation, this.ITransportContext.BinaryHostIdentifier, HttpPacketType.Usual, message.MessageId, string.Empty, this.Remote.LocalHostUniqueIdentifier);
                if (stream.CanSeek)
                {
                    resultStream.WriteStream(stream);
                }
                else
                {
                    GenuineUtility.CopyStreamToStream(stream, resultStream);
                }

                // get a connection
                availableConnectionEntry = FindAvailableConnectionEntry();
                httpWebRequest           = this.InitializeRequest("__GC_INVC_" + availableConnectionEntry.ToString(), this._keepalive);

                this.InitiateSending(new ConnectionInfo(httpWebRequest, availableConnectionEntry, message), resultStream,
                                     this._httpAsynchronousRequestTimeout);
            }
            catch
            {
                try
                {
                    if (httpWebRequest != null)
                    {
                        httpWebRequest.Abort();
                    }
                }
                catch
                {
                }

                this.ReleaseConnectionEntry(availableConnectionEntry);

                throw;
            }
        }
示例#10
0
        public void SendTestMessage()
        {
            CMD_BASE_MESSAGE rep = new CMD_BASE_MESSAGE();

            rep.Cmd     = 11;
            rep.Message = "bsadsdfasf";

            MemoryStream ms = MessageTransformation.Serialize <CMD_BASE_MESSAGE>(rep);

            byte[] entityData = ms.ToArray();

            byte[] messagedate = MessageCoder.MessageEncoding(entityData);

            _socket.Send(messagedate, messagedate.Length, 0);
        }
示例#11
0
        /// <summary>
        /// Encrypts the stream under current security conditions.
        /// </summary>
        /// <param name="messageStream">Data to be encrypted.</param>
        /// <param name="outputStream">Stream to write encrypted content to.</param>
        /// <param name="sspiFeatureFlags">Requested features.</param>
        public void EncryptMessage(Stream messageStream, GenuineChunkedStream outputStream, SspiFeatureFlags sspiFeatureFlags)
        {
            // get package sizes
            lock (_secPkgContext_SizesLock)
            {
                if (!_secPkgContext_SizesInitialized)
                {
                    SspiApi.QueryContextSizes(this._phContext, ref this._secPkgContext_Sizes);
                    _secPkgContext_SizesInitialized = true;
                }
            }

            byte[]       chunk        = null;
            int          position     = 0;
            BinaryWriter outputWriter = new BinaryWriter(outputStream);

            if ((sspiFeatureFlags & SspiFeatureFlags.Encryption) != 0)
            {
                // it'll write signature automatically as well as encrypt content
                SspiApi.EncryptMessage(this._phContext, messageStream, outputWriter, ref this._secPkgContext_Sizes);
            }
            else if ((sspiFeatureFlags & SspiFeatureFlags.Signing) != 0)
            {
                // remember position to write signature size later
                outputStream.WriteInt32AndRememberItsLocation(0, out chunk, out position);
                long currentLength = outputStream.Length;

                // anyway will have to read this into buffer
                byte[] contentBuffer = new byte[(int)messageStream.Length];
                GenuineUtility.ReadDataFromStream(messageStream, contentBuffer, 0, contentBuffer.Length);

                // write signature
                SspiApi.MakeSignature(this._phContext, contentBuffer, outputWriter, ref this._secPkgContext_Sizes);

                // update signature size
                MessageCoder.WriteInt32(chunk, position, (int)(outputStream.Length - currentLength));

                // write the content
                outputWriter.Write((int)contentBuffer.Length);
                outputWriter.Write(contentBuffer, 0, contentBuffer.Length);
            }
            else
            {
                // just copy the source content
                //outputWriter.Write( (int) messageStream.Length );
                GenuineUtility.CopyStreamToStream(messageStream, outputStream);
            }
        }
示例#12
0
        static void Main(string[] args)
        {
            const string quitInput = "quit";                // The value to use to indicate that you want to quit the program.
            string       queueName = Constants.ChannelName; // The queue name.

            PrintHeader(quitInput);                         // Prints the header and the instuctions.

            // Setup the communications to the MQ service.
            LocalConnectionFactory factory    = new LocalConnectionFactory();
            IConnection            connection = factory.CreateConnection();
            IModel model = connection.CreateModel();

            model.QueueDeclare(queueName, false, false, false, null);


            // Start the input loop.
            string message;

            byte[]       body;
            MessageCoder messageCoder = new MessageCoder();
            string       nameInput    = GetConsoleInputForName();

            while (nameInput.ToLower() != quitInput)
            {
                // Build the message using our very sofisticated protocol.
                messageCoder.Name = nameInput;
                message           = messageCoder.Encode();

                // The body for the communication must be a byte array.
                body = Encoding.UTF8.GetBytes(message);

                // Publish the message to the queue.
                model.BasicPublish("", queueName, null, body);

                // Indicate that the message was send.
                IndicateSend(message);

                nameInput = GetConsoleInputForName();
            }

            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("Shutting down Publisher Side...");

            // Close down the communications.
            model.Close();
            connection.Close();
        }
示例#13
0
        /// <summary>
        /// Handles the messages received by this consumer.
        /// </summary>
        /// <remarks>There is no exception handling here. Hanlding invalid responses should be a normal part of the flow.</remarks>
        private static void Consumer_Received(object sender, BasicDeliverEventArgs e)
        {
            var body    = e.Body;
            var message = Encoding.UTF8.GetString(body);

            MessageCoder coder = new MessageCoder();

            // Try and decode the message.
            if (coder.Decode(message))
            {
                PrintValidMessageRecieved(coder.Name);
            }
            else
            {
                IndicateInvalidMessageRecieved(message);
            }
        }
示例#14
0
        void CreatOneConnect()
        {
            try
            {
                int    port = 2012;
                string host = "127.0.0.1";
                //string host = "134.175.17.67";

                IPAddress  ip  = IPAddress.Parse(host);
                IPEndPoint ipe = new IPEndPoint(ip, port);                                                    //把ip和端口转化为IPEndPoint实例
                Socket     c   = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //创建一个Socket
                Console.WriteLine("Conneting...");
                c.Connect(ipe);                                                                               //连接到服务器


                CMD_BASE_MESSAGE rep = new CMD_BASE_MESSAGE();
                rep.Cmd     = 11;
                rep.Message = "bsadsdfasf";


                MemoryStream ms = MessageTransformation.Serialize <CMD_BASE_MESSAGE>(rep);

                byte[] entityData = ms.ToArray();

                byte[] messagedate = MessageCoder.MessageEncoding(entityData);

                c.Send(messagedate, messagedate.Length, 0);
                c.Send(messagedate, messagedate.Length, 0);
                c.Send(messagedate, messagedate.Length, 0);
                c.Send(messagedate, messagedate.Length, 0);
                c.Send(messagedate, messagedate.Length, 0);
                c.Send(messagedate, messagedate.Length, 0);

                Console.Write("断开连接");
                c.Close();
            }
            catch (ArgumentNullException e)
            {
                Console.WriteLine("ArgumentNullException: {0}", e);
            }
            catch (SocketException e)
            {
                Console.WriteLine("SocketException: {0}", e);
            }
        }
示例#15
0
        public static async Task <int> WriteAsync(TcpClient client, IMessageProtocol messageProtocol)
        {
            if (client.Connected)
            {
                var ns = client.GetStream();

                if (ns.CanWrite)
                {
                    var bytes = MessageCoder.Encode(messageProtocol);
                    await ns.WriteAsync(bytes, 0, bytes.Length);

                    await ns.FlushAsync();

                    return(bytes.Length);
                }
            }

            return(0);
        }
示例#16
0
        private void PushLocalBuffer(byte[] buffer, int offset, int count)
        {
            if ((_ReceiveOffset + count) > _ReceiveBuffer.Length)
            {
                LogHelper.Error("客户端信息数据超出当前接收缓存大小!");
                throw new Exception("客户端信息数据超出当前接收缓存大小!");
            }

            Array.Copy(buffer, offset, _ReceiveBuffer, _ReceiveOffset, count);

            _ReceiveOffset += count;

            //LogHelper.Debug("添加数据缓存 当前缓存长度:{0}", _ReceiveOffset);

            List <byte[]> messagebuffers = MessageCoder.MessageDecoding(ref _ReceiveBuffer, ref _ReceiveOffset);

            foreach (var mm in messagebuffers)
            {
                MemoryStream ms = new MemoryStream(mm, 0, mm.Length);

                _CurServerEngine.AddReceiveCommand(ms, this);
            }
        }
示例#17
0
        private void PushLocalBuffer(byte[] buffer, int offset, int count)
        {
            if ((_ReceiveOffset + count) > _ReceiveBuffer.Length)
            {
                throw new Exception("客户端信息数据超出当前接收缓存大小!");
            }

            Array.Copy(buffer, offset, _ReceiveBuffer, _ReceiveOffset, count);

            _ReceiveOffset += count;

            Console.WriteLine("添加数据缓存 当前缓存长度:{0}", _ReceiveOffset);

            List <byte[]> messagebuffers = MessageCoder.MessageDecoding(ref _ReceiveBuffer, ref _ReceiveOffset);

            foreach (var mm in messagebuffers)
            {
                MemoryStream ms = new MemoryStream(mm, 0, mm.Length);

                CMD_BASE_MESSAGE mss2 = MessageTransformation.Deserialize <CMD_BASE_MESSAGE>(ms);

                strReceiveMessage += "|" + mss2.Message;
            }
        }
        /// <summary>
        /// Synchronously reads the next network packet if it is available.
        /// </summary>
        /// <param name="deriveHeader">Indicates whether it is necessary to take header from the provided connection.</param>
        private void ReadNextPortion(bool deriveHeader)
        {
            int bytesRead    = 0;
            int lengthToRead = 0;

            if (!deriveHeader)
            {
                // try to read the remaining part of the packet
                if (this._currentPacketBytesRead < this._currentPacketSize)
                {
                    // read the next part of the packet
                    lengthToRead = Math.Min(this._currentPacketSize - this._currentPacketBytesRead, this._readBuffer.Length);

                    this._validLength = this.ReadFromSocket(this._readBuffer, 0, lengthToRead);
                    if (this._validLength == 0)
                    {
                        throw GenuineExceptions.Get_Receive_Portion();
                    }

                    // Fixed in 2.5.9.7
                    //this._tcpSocketInfo.ITransportContext.ConnectionManager.IncreaseBytesReceived(this._validLength);
                    this._currentPacketBytesRead += this._validLength;
                    this._currentPosition         = 0;

                    if (this._currentPacketBytesRead == this._currentPacketSize && this._messageRead)
                    {
                        this.ReadingCompleted();
                    }
                    return;
                }

                // the underlying stream ends
                if (this._messageRead)
                {
                    return;
                }

                // prepare for reading a header
                this._currentPosition = 0;
            }

            lengthToRead = TcpConnectionManager.HEADER_SIZE;

            if (deriveHeader)
            {
                if (this._tcpSocketInfo.ReceivingBufferCurrentPosition > 0)
                {
                    Buffer.BlockCopy(this._tcpSocketInfo.ReceivingHeaderBuffer, 0, this._readBuffer, 0, this._tcpSocketInfo.ReceivingBufferCurrentPosition);
                }
                this._currentPosition = this._tcpSocketInfo.ReceivingBufferCurrentPosition;
            }

            // read the header
            while (this._currentPosition < lengthToRead)
            {
                bytesRead = this.ReadFromSocket(this._readBuffer, this._currentPosition, lengthToRead - this._currentPosition);

                if (bytesRead == 0)
                {
                    throw GenuineExceptions.Get_Receive_Portion();
                }

                // Fixed in 2.5.9.7
                //this._tcpSocketInfo.ITransportContext.ConnectionManager.IncreaseBytesReceived(bytesRead);
                this._currentPosition += bytesRead;
            }

            // parse the header
            if (this._readBuffer[0] != MessageCoder.COMMAND_MAGIC_CODE)
            {
                throw GenuineExceptions.Get_Receive_IncorrectData();
            }
            this._currentPacketSize      = MessageCoder.ReadInt32(this._readBuffer, 1);
            this._messageRead            = this._readBuffer[5] != 0;
            this._currentPacketBytesRead = 0;

            // and read the part of the packet
            if (this._currentPacketBytesRead < this._currentPacketSize)
            {
                // read the next part of the packet
                lengthToRead = Math.Min(this._currentPacketSize - this._currentPacketBytesRead, this._readBuffer.Length);

                this._validLength = this.ReadFromSocket(this._readBuffer, 0, lengthToRead);
                if (this._validLength == 0)
                {
                    throw GenuineExceptions.Get_Receive_Portion();
                }

                // Fixed in 2.5.9.7
                //this._tcpSocketInfo.ITransportContext.ConnectionManager.IncreaseBytesReceived(this._validLength);
                this._currentPacketBytesRead += this._validLength;
                this._currentPosition         = 0;
            }

            if (this._currentPacketBytesRead == this._currentPacketSize && this._messageRead)
            {
                this.ReadingCompleted();
            }
        }
示例#19
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();
                }
            }
        }
示例#20
0
 public IMessageProtocol ToMessageProtocol()
 {
     return(Bytes?.Length > 0 ? MessageCoder.Decode(Bytes) : null);
 }
        /// <summary>
        /// Opens a connection to the host specified by the url.
        /// </summary>
        /// <param name="remote">The HostInformation of the Remote Host.</param>
        /// <param name="localUri">The uri of the local host.</param>
        /// <param name="remoteUri">The uri of the remote host.</param>
        /// <param name="remoteHostUniqueIdentifier">The unique identifier of the HostInformation used by the remote host.</param>
        /// <returns>The established connection.</returns>
        private SharedMemoryConnection LowLevel_OpenConnection(HostInformation remote, string localUri, out string remoteUri, out int remoteHostUniqueIdentifier)
        {
            using (new ReaderAutoLocker(this._disposeLock))
            {
                if (this._disposed)
                {
                    throw OperationException.WrapException(this._disposeReason);
                }
            }

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

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

            IParameterProvider parameters = this.ITransportContext.IParameterProvider;

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

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

            // LOG:
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;

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

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

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

            connectionInformation.Write(shareName);

            // let the server know that a client's share is ready
            Mutex mutex = null;

            try
            {
                mutex = WindowsAPI.OpenMutex(mutexName);

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

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

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

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

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

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

            // get the connection-level Security Session
            string          connectionLevelSSName = this.ITransportContext.IParameterProvider[GenuineParameter.SecuritySessionForPersistentConnections] as string;
            SecuritySession securitySession       = null;

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

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

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

                        outputStream = securitySession.EstablishSession(inputStream, true);

                        if (outputStream == null)
                        {
                            break;
                        }

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

            sharedMemoryConnection.ConnectionLevelSecurity = securitySession;

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

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

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

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

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

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

            return(sharedMemoryConnection);
        }
        /// <summary>
        /// Sends a message to the remote host.
        /// </summary>
        /// <param name="message">The message to be sent.</param>
        public void Send(Message message)
        {
#if TRIAL
            _messagesBeingSent[message.MessageId] = message;
#endif

            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;

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

                SecuritySession session = null;

                if (this._disposed)
                {
                    throw OperationException.WrapException(this._disposeReason);
                }

                // get the security session descriptor
                if (message.SecuritySessionParameters == null)
                {
                    SecuritySessionParameters securitySessionParameters = SecuritySessionServices.GetCurrentSecurityContext();
                    if (securitySessionParameters == null)
                    {
                        securitySessionParameters = message.Recipient.SecuritySessionParameters;
                    }
                    if (securitySessionParameters == null)
                    {
                        securitySessionParameters = this.ITransportContext.SecuritySessionParameters;
                    }
                    if (securitySessionParameters == null)
                    {
                        securitySessionParameters = SecuritySessionServices.DefaultSecuritySession;
                    }
                    message.SecuritySessionParameters = securitySessionParameters;
                }

                // LOG:
                if (binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0)
                {
                    binaryLogWriter.WriteSecuritySessionParametersEvent("ConnectionManager.Send",
                                                                        LogMessageType.SecuritySessionParametersAssembled, null, message, message.Recipient,
                                                                        GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                                        message.SecuritySessionParameters,
                                                                        "Security Session Parameters have been assembled.");
                }

                // determine the type of sending
                message.IsSynchronous = (message.SecuritySessionParameters.Attributes & SecuritySessionAttributes.ForceSync) != 0 ||
                                        (message.IsSynchronous && (message.SecuritySessionParameters.Attributes & SecuritySessionAttributes.ForceAsync) == 0);

                // the time until invocation times out
                if (!message.FinishTime_Initialized)
                {
                    TimeSpan messageTimeout = message.SecuritySessionParameters.Timeout;
                    if (messageTimeout == TimeSpan.MinValue)
                    {
                        messageTimeout = (TimeSpan)this.ITransportContext.IParameterProvider[GenuineParameter.InvocationTimeout];
                    }
                    message.FinishTime = GenuineUtility.GetTimeout(messageTimeout);

                    message.FinishTime_Initialized = true;
                }

                // checks whether the message has been already processed by Security Session
                if (message.SerializedContent == null)
                {
                    session = message.Recipient.GetSecuritySession(message.SecuritySessionParameters.Name, this.ITransportContext.IKeyStore);
                    if (!session.IsEstablished)
                    {
                        if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0)
                        {
                            binaryLogWriter.WriteEvent(LogCategory.Security, "ConnectionManager.Send",
                                                       LogMessageType.SecuritySessionHasNotBeenEstablishedYet, null, message, message.Recipient, null,
                                                       GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                       session, session.Name, -1, 0, 0, 0, null, null, null, null,
                                                       "The requested Security Session is not established.");
                        }

                        session.InitiateEstablishingSecuritySession(message.SecuritySessionParameters);

                        // if it's a sync sending, then wait until security session will be established
                        if (message.IsSynchronous)
                        {
                            int timeSpanToWait = GenuineUtility.GetMillisecondsLeft(message.FinishTime);
                            if (timeSpanToWait <= 0)
                            {
                                throw GenuineExceptions.Get_Send_ServerDidNotReply();
                            }

                            // wait until Security Session will be established or a failure will be detected
                            int firedEvent = 0;
                            if (message.CancelSending != null)
                            {
                                firedEvent = WaitHandle.WaitAny(new WaitHandle[] { session.IsEstablishedEvent, session.Failed, message.CancelSending }, timeSpanToWait, false);
                            }
                            else
                            {
                                firedEvent = WaitHandle.WaitAny(new WaitHandle[] { session.IsEstablishedEvent, session.Failed }, timeSpanToWait, false);
                            }

                            if (firedEvent == WaitHandle.WaitTimeout)
                            {
                                throw GenuineExceptions.Get_Send_ServerDidNotReply();
                            }

                            // analyze the problem, if any
                            Exception exception = session.ReasonOfFailure;
                            if (firedEvent == 1)
                            {
                                if (exception != null)
                                {
                                    throw OperationException.WrapException(exception);
                                }
                                else
                                {
                                    throw GenuineExceptions.Get_Security_ContextWasNotEstablished(session.Name);
                                }
                            }

                            // if the message has been cancelled, let the sender to understand the reason
                            if (firedEvent == 2)
                            {
                                return;
                            }
                        }
                        else if (!session.IsEstablished)
                        {
                            // it's async and SS still isn't established
                            session.PutMessageToAwaitingQueue(message);
                            return;
                        }
                    }
                }

                // if serialization is necessary
                if (message.SerializedContent == null)
                {
                    // serialize the message
                    GenuineChunkedStream serializedMessageStream = new GenuineChunkedStream(false);
                    MessageCoder.Serialize(serializedMessageStream, message, (message.SecuritySessionParameters.Attributes & SecuritySessionAttributes.EnableCompression) != 0);

                    // save the name of the Security Session
                    GenuineChunkedStream resultStream = new GenuineChunkedStream(false);
                    BinaryWriter         writer       = new BinaryWriter(resultStream);
                    writer.Write(message.SecuritySessionParameters.Name);
                    session.Encrypt(serializedMessageStream, resultStream);
                    message.SerializedContent = resultStream;

                    // LOG: put down the log record
                    if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0)
                    {
                        binaryLogWriter.WriteEvent(LogCategory.Security, "ConnectionManager.Send",
                                                   LogMessageType.SecuritySessionApplied, null, message, message.Recipient,
                                                   binaryLogWriter[LogCategory.Security] > 1 ? message.SerializedContent : null,
                                                   GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, session,
                                                   session.Name, -1, 0, 0, 0, null, null, null, null,
                                                   "The message has been processed by the established Security Session.");
                    }
                }

#if TRIAL
                if (message.MessageId > 3005)
                {
                    throw GenuineExceptions.Get_Channel_TrialConditionExceeded("The maximum number of messages restriction has been exceeded. You can not send more than 3000 messages using TRIAL version.");
                }
#endif

                message.Sender = this.Local;
                this.InternalSend(message);
            }
            catch (Exception ex)
            {
                if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0)
                {
                    binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "ConnectionManager.Send",
                                               LogMessageType.Error, ex, message, message.Recipient, null,
                                               GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                               null, null, -1, 0, 0, 0, null, null, null, null,
                                               "An exception occurred while processing the message.");
                }

                throw;
            }
        }
示例#23
0
        /// <summary>
        /// Receives the content synchronously.
        /// </summary>
        private void ReceiveSynchronously()
        {
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;

            byte[] receiveBuffer = null;
            this._receivingThreadClosed.Reset();

            try
            {
                int mtu = (int)this.ITransportContext.IParameterProvider[GenuineParameter.UdpMtu];
                for ( ; ;)
                {
                    if (this._closing)
                    {
                        return;
                    }

                    if (BufferPool.GENERAL_BUFFER_SIZE >= mtu)
                    {
                        receiveBuffer = BufferPool.ObtainBuffer();
                    }
                    else
                    {
                        receiveBuffer = new byte[mtu];
                    }

                    try
                    {
                        IPEndPoint ipEndPoint        = new IPEndPoint(IPAddress.Any, 0);
                        EndPoint   endPointReference = ipEndPoint;
                        int        bytesReceived     = this._socket.ReceiveFrom(receiveBuffer, 0, receiveBuffer.Length, SocketFlags.None, ref endPointReference);
                        ipEndPoint = (IPEndPoint)endPointReference;

                        // LOG:
                        if (binaryLogWriter != null && binaryLogWriter[LogCategory.Transport] > 0)
                        {
                            binaryLogWriter.WriteTransportContentEvent(LogCategory.Transport, "UdpConnectionManager.ReceiveSynchronously",
                                                                       LogMessageType.ReceivingFinished, null, null, null,
                                                                       binaryLogWriter[LogCategory.Transport] > 1 ? new MemoryStream(GenuineUtility.CutOutBuffer(receiveBuffer, 0, bytesReceived)) : null,
                                                                       GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                                       this.DbgConnectionId, bytesReceived, ipEndPoint.ToString(),
                                                                       null, null,
                                                                       "Content is received from {0}.", ipEndPoint.ToString());
                        }

                        // parse the header
                        if (bytesReceived < HEADER_SIZE)
                        {
                            throw GenuineExceptions.Get_Receive_IncorrectData();
                        }
                        if (receiveBuffer[0] != MessageCoder.COMMAND_MAGIC_CODE)
                        {
                            throw GenuineExceptions.Get_Receive_IncorrectData();
                        }

                        // get the packet identifier
                        byte[] guidBuffer = new byte[16];
                        Buffer.BlockCopy(receiveBuffer, 1, guidBuffer, 0, 16);
                        Guid packetGuid = new Guid(guidBuffer);

                        // and chunk number
                        int  chunkNumber = MessageCoder.ReadInt32(receiveBuffer, 17);
                        bool isLast      = chunkNumber < 0;
                        if (chunkNumber < 0)
                        {
                            chunkNumber = -chunkNumber;
                        }
                        chunkNumber--;

                        // process the chunk
                        StreamAssembled streamAssembled;
                        lock (this._streams.SyncRoot)
                        {
                            streamAssembled = this._streams[packetGuid] as StreamAssembled;
                            if (streamAssembled == null)
                            {
                                this._streams[packetGuid] = streamAssembled = new StreamAssembled(ipEndPoint, HEADER_SIZE);
                            }
                            if (streamAssembled.IsProcessed)
                            {
                                continue;
                            }
                        }

                        string          uri    = "gudp://" + ipEndPoint.ToString();
                        HostInformation remote = this.ITransportContext.KnownHosts[uri];
                        remote.Renew(this._closeInvocationConnectionAfterInactivity, false);

                        if ((int)this.ITransportContext.IParameterProvider[GenuineParameter.CompatibilityLevel] <= 0)
                        {
                            remote.UpdateUri(uri, 0, false);
                        }

                        if (streamAssembled.BufferReceived(chunkNumber, receiveBuffer, bytesReceived, isLast))
                        {
                            // prepare it for processing
                            this._streams.Remove(packetGuid);
                            streamAssembled.IsProcessed = true;

                            // read the remote host URI
                            if ((int)this.ITransportContext.IParameterProvider[GenuineParameter.CompatibilityLevel] > 0)
                            {
                                BinaryReader binaryReader = new BinaryReader(streamAssembled);

                                // read the URI
                                byte[] uriBuffer = new byte[16];
                                GenuineUtility.ReadDataFromStream(streamAssembled, uriBuffer, 0, uriBuffer.Length);
                                Guid   remoteHostUriGuid = new Guid(uriBuffer);
                                string receivedUri       = "_gudp://" + remoteHostUriGuid.ToString("N");

                                // read the remote host unique identifier
                                int remoteHostUniqueIdentifier = binaryReader.ReadInt32();

                                // update the host information
                                remote.UpdateUri(receivedUri, remoteHostUniqueIdentifier, false);

                                // and skip the skip space
                                GenuineUtility.CopyStreamToStream(streamAssembled, Stream.Null, binaryReader.ReadInt16());
                            }

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

                            remote.PhysicalAddress = endPointReference;
                            this.ITransportContext.IIncomingStreamHandler.HandleMessage(streamAssembled, remote, GenuineConnectionType.Persistent, string.Empty, -1, false, this._iMessageRegistrator, null, null);
                        }
                    }
                    catch (Exception ex)
                    {
                        // LOG:
                        if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0)
                        {
                            binaryLogWriter.WriteEvent(LogCategory.Connection, "UdpConnectionManager.ReceiveSynchronously",
                                                       LogMessageType.ReceivingFinished, ex, null, null, null,
                                                       GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                       null, null,
                                                       this.DbgConnectionId, 0, 0, 0, null, null, null, null,
                                                       "UDP socket failure.");
                        }

                        if (this._closing)
                        {
                            return;
                        }

                        this.ITransportContext.IGenuineEventProvider.Fire(new GenuineEventArgs(GenuineEventType.GUdpSocketException, ex, this.Local, null));
                    }
                }
            }
            finally
            {
                this._receivingThreadClosed.Set();
            }
        }
示例#24
0
        /// <summary>
        /// Sends the message to the remote host.
        /// </summary>
        /// <param name="message">The message to be sent.</param>
        protected override void InternalSend(Message message)
        {
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;

            // get IP end point of the remote host
            IPEndPoint remoteEndPoint;

            if (message.Recipient.Uri != null && message.Recipient.Uri.StartsWith("_gb"))
            {
                remoteEndPoint = this._multicastTo;
            }
            else
            {
                remoteEndPoint = message.Recipient.PhysicalAddress as IPEndPoint;
            }
            if (remoteEndPoint == null)
            {
                try
                {
                    int    port;
                    string baseUrl = GenuineUtility.SplitToHostAndPort(message.Recipient.Url, out port);
                    message.Recipient.PhysicalAddress = remoteEndPoint = new IPEndPoint(GenuineUtility.ResolveIPAddress(baseUrl), port);
                }
                catch (Exception)
                {
                    throw GenuineExceptions.Get_Send_DestinationIsUnreachable(message.Recipient.ToString());
                }
            }

            Stream streamToSend = message.SerializedContent;

            // write the host URI
            if ((int)this.ITransportContext.IParameterProvider[GenuineParameter.CompatibilityLevel] > 0)
            {
                GenuineChunkedStream streamWith250Header = new GenuineChunkedStream(false);
                BinaryWriter         binaryWriter        = new BinaryWriter(streamWith250Header);
                streamWith250Header.Write(this.ITransportContext.BinaryHostIdentifier, 0, this.ITransportContext.BinaryHostIdentifier.Length);
                binaryWriter.Write((int)message.Recipient.LocalHostUniqueIdentifier);
                binaryWriter.Write((Int16)0);

                streamWith250Header.WriteStream(streamToSend);

                streamToSend = streamWith250Header;
            }

            // LOG:
            if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0)
            {
                binaryLogWriter.WriteEvent(LogCategory.Connection, "UdpConnectionManager.InternalSend",
                                           LogMessageType.MessageIsSentSynchronously, null, message, message.Recipient, null,
                                           GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                           message.ConnectionLevelSecuritySession, message.ConnectionLevelSecuritySession == null ? null : message.ConnectionLevelSecuritySession.Name,
                                           -1, 0, 0, 0, remoteEndPoint.ToString(), null, null, null,
                                           "The message is being sent synchronously to {0}.", remoteEndPoint.ToString());
            }

            // send the message
            byte[] streamId = Guid.NewGuid().ToByteArray();

            lock (_socketLock)
            {
                for (int chunkNumber = 1; ; chunkNumber++)
                {
                    // read the next chunk
                    int chunkSize = streamToSend.Read(this._sendBuffer, HEADER_SIZE, this._sendBuffer.Length - HEADER_SIZE);

                    // fill in the header
                    this._sendBuffer[0] = MessageCoder.COMMAND_MAGIC_CODE;
                    Buffer.BlockCopy(streamId, 0, this._sendBuffer, 1, 16);
                    if (chunkSize < this._sendBuffer.Length - HEADER_SIZE)
                    {
                        chunkNumber = -chunkNumber;
                    }
                    MessageCoder.WriteInt32(this._sendBuffer, 17, chunkNumber);

                    // and just send it!

                    // LOG:
                    if (binaryLogWriter != null && binaryLogWriter[LogCategory.Transport] > 0)
                    {
                        binaryLogWriter.WriteTransportContentEvent(LogCategory.Transport, "UdpConnectionManager.InternalSend",
                                                                   LogMessageType.SynchronousSendingStarted, null, message, message.Recipient,
                                                                   binaryLogWriter[LogCategory.Transport] > 1 ? new MemoryStream(GenuineUtility.CutOutBuffer(this._sendBuffer, 0, chunkSize + HEADER_SIZE)) : null,
                                                                   GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                                   this.DbgConnectionId, chunkSize + HEADER_SIZE, remoteEndPoint.ToString(),
                                                                   null, null,
                                                                   "Content is sent synchronously to {0}.", remoteEndPoint.ToString());
                    }

                    this._socket.SendTo(this._sendBuffer, 0, chunkSize + HEADER_SIZE, SocketFlags.None, remoteEndPoint);

                    if (chunkNumber < 0)
                    {
                        break;
                    }
                }
            }
        }