/// <summary> /// Encrypts the message data and put a result into the specified output stream. /// </summary> /// <param name="input">The stream containing the serialized message.</param> /// <param name="output">The result stream with the data being sent to the remote host.</param> public override void Encrypt(Stream input, GenuineChunkedStream output) { #if DEBUG input.Position = 0; #endif output.WriteByte(1); lock (this) { // write encrypted content if (this._encryptor != null) { GenuineUtility.CopyStreamToStream(new CryptoStream(new FinishReadingStream(input), this._encryptor, CryptoStreamMode.Read), output); } else { output.WriteStream(input); } if (this.KeyedHashAlgorithm != null) { // and write down the calculated message hash input.Position = 0; output.WriteBuffer(this.KeyedHashAlgorithm.ComputeHash(input), -1); // it's in the content, reset its position if (this._encryptor == null) { input.Position = 0; } } } }
/// <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; } }
/// <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; } } } }
/// <summary> /// Encrypts the message data and put a result into the specified output stream. /// </summary> /// <param name="input">The stream containing the serialized message.</param> /// <param name="output">The result stream with the data being sent to the remote host.</param> public override void Encrypt(Stream input, GenuineChunkedStream output) { output.WriteStream(input); }