public void CreatedWithEmptyName() { MessageCoder coder = new MessageCoder(); Assert.NotNull(coder); Assert.Equal(string.Empty, coder.Name); }
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; } }
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); }
/// <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); } }
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(); }
/// <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); } }
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); } }
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); }
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); } }
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(); } }
/// <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(); } } }
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; } }
/// <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(); } }
/// <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; } } } }