/// <summary> /// Write a message to the SSL stream /// </summary> /// <param name="type">Type of message</param> /// <param name="messageBytes">Byte array of serialized message</param> /// <param name="cancellationToken">The token to monitor for cancellation requests</param> /// <returns>Empty task</returns> private async Task WriteMessageAsync(MessageType type, byte[] messageBytes, CancellationToken cancellationToken) { var typeBytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)type)); var sizeBytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(messageBytes.Length)); await this.writeSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); using (var cts = cancellationToken.AddTimeout(WriteTimeout)) { await this.sslStream.WriteAsync(typeBytes, 0, typeBytes.Length, cts.Token) .HandleTimeout(cts.Token).ConfigureAwait(false); await this.sslStream.WriteAsync(sizeBytes, 0, sizeBytes.Length, cts.Token) .HandleTimeout(cts.Token).ConfigureAwait(false); await this.sslStream.WriteAsync(messageBytes, 0, messageBytes.Length, cts.Token) .HandleTimeout(cts.Token).ConfigureAwait(false); } this.writeSemaphore.Release(); }
/// <inheritdoc /> public async Task<IMessage> ReadMessageAsync(CancellationToken cancellationToken, int timeout = Timeout.Infinite) { var headerBytes = new byte[6]; using (var cts = cancellationToken.AddTimeout(timeout)) { await this.sslStream.ReadAsync(headerBytes, 0, headerBytes.Length, cts.Token) .HandleTimeout(cts.Token).ConfigureAwait(false); } var type = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(headerBytes, 0)); var size = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(headerBytes, 2)); var messageBytes = new byte[size]; using (var cts = cancellationToken.AddTimeout(timeout)) { await this.sslStream.ReadAsync(messageBytes, 0, size, cts.Token) .HandleTimeout(cts.Token).ConfigureAwait(false); } if (type == (int)MessageType.UDPTunnel) { return new UDPTunnel.Builder { Packet = ByteString.CopyFrom(messageBytes) }.Build(); } else { return this.messageFactory.Deserialize((MessageType)type, ByteString.CopyFrom(messageBytes)); } }