public async Task <IPacketHeader> ReadHeaderAsync(CancellationToken token) { //If the token is canceled just return null; if (token.IsCancellationRequested) { return(null); } //If we had access to the stream we could wrap it in a reader and use it //without knowing the size. Since we don't have access we must manually read int count = await DecoratedClient.ReadAsync(PacketHeaderBuffer, 0, PacketHeaderBuffer.Length, token) .ConfigureAwait(false); //TODO: How long should the timeout be if any? //This means the socket is disconnected if (count == 0) { return(null); } //If the token is canceled just return null; if (token.IsCancellationRequested) { return(null); } //This will deserialize return(Serializer.Deserialize <TPacketHeaderType>(PacketHeaderBuffer)); }
private async Task <bool> ReadAndDecrypt(byte[] buffer, int start, CancellationToken token, int extendedCount) { //We don't need to know the amount read, I think. int count = await DecoratedClient.ReadAsync(buffer, start, extendedCount, token) .ConfigureAwait(false); //IF we read nothing then that means the socket disconnected if (count == 0) { return(false); } //Check cancel again, we want to fail quick if (token.IsCancellationRequested) { return(false); } //We throw above if we have an invalid size that can't be decrypted once read. //That means callers will need to be careful in what they request to read. DecryptionServiceProvider.Crypt(buffer, start, extendedCount); //Check cancel again, we want to fail quick if (token.IsCancellationRequested) { return(false); } return(true); }
/// <inheritdoc /> public override async Task ClearReadBuffers() { using (await ReadBuffer.BufferLock.LockAsync().ConfigureAwait(false)) { //Reset the crypto buffer CryptoBlockOverflowReadIndex = CryptoBlockOverflow.Length; await DecoratedClient.ClearReadBuffers() .ConfigureAwait(false); } }
/// <inheritdoc /> public async Task <int> WriteHeaderAsync(IPacketHeader header) { //We only need to serialize and then write byte[] bytes = Serializer.Serialize(header); await DecoratedClient.WriteAsync(bytes) .ConfigureAwait(false); return(bytes.Length); }
/// <inheritdoc /> public async Task WriteAsync(TWritePayloadBaseType payload) { //Serializer the payload first so we can build the header byte[] payloadData = Serializer.Serialize(payload); using (await writeSynObj.LockAsync().ConfigureAwait(false)) { //Write the outgoing message await DecoratedClient.WriteAsync(payloadData) .ConfigureAwait(false); } }
public override Task WriteAsync(byte[] bytes, int offset, int count) { if (offset < 0) { throw new ArgumentOutOfRangeException(nameof(offset)); } if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count)); } return(DecoratedClient.WriteAsync(EncryptionServiceProvider.Crypt(bytes, offset, count), offset, count)); }
/// <summary> /// The Execute. /// </summary> /// <param name="request">The request<see cref="IRestRequest"/>.</param> /// <returns>The <see cref="IRestResponse"/>.</returns> public override IRestResponse Execute(IRestRequest request) { InjectAccessToken(request); IRestResponse response = DecoratedClient.Execute(request); if (response.StatusCode == HttpStatusCode.Unauthorized) { RefreshAccessToken(); InjectAccessToken(request); response = DecoratedClient.Execute(request); } return(response); }
/// <summary> /// The ExecuteTaskAsync. /// </summary> /// <typeparam name="T">.</typeparam> /// <param name="request">The request<see cref="IRestRequest"/>.</param> /// <param name="token">The token<see cref="CancellationToken"/>.</param> /// <returns>The <see cref="Task{IRestResponse{T}}"/>.</returns> public override async Task <IRestResponse <T> > ExecuteTaskAsync <T>(IRestRequest request, CancellationToken token) { InjectAccessToken(request); IRestResponse <T> response = await DecoratedClient.ExecuteTaskAsync <T>(request, token); if (response.StatusCode == HttpStatusCode.Unauthorized) { RefreshAccessToken(); InjectAccessToken(request); response = await DecoratedClient.ExecuteTaskAsync <T>(request, token); } return(response); }
/// <summary> /// The ExecuteTaskAsync. /// </summary> /// <param name="request">The request<see cref="IRestRequest"/>.</param> /// <returns>The <see cref="Task{IRestResponse}"/>.</returns> public override async Task <IRestResponse> ExecuteTaskAsync(IRestRequest request) { InjectAccessToken(request); IRestResponse response = await DecoratedClient.ExecuteTaskAsync(request); if (response.StatusCode == HttpStatusCode.Unauthorized) { RefreshAccessToken(); InjectAccessToken(request); response = await DecoratedClient.ExecuteTaskAsync(request); } return(response); }
/// <inheritdoc /> public async Task <NetworkIncomingMessage <TReadPayloadBaseType> > ReadAsync(CancellationToken token) { using (await ReadLock.LockAsync(token).ConfigureAwait(false)) { //We want to clear the read buffers after reaiding a full message. NetworkIncomingMessage <TReadPayloadBaseType> message = await DecoratedClient.ReadAsync(token) .ConfigureAwait(false); //Do not call the object's ClearBuffer or we will deadlock; isn't re-enterant await DecoratedClient.ClearReadBuffers() .ConfigureAwait(false); //Could be null if the socket disconnected return(message); } }
private async Task CryptAndSend(byte[] payloadData, int offset, int payloadBytesCount) { //VERY critical we lock here otherwise we could write a header and then another unrelated body could be written inbetween using (await writeSynObj.LockAsync().ConfigureAwait(!GladMMOAsyncSettings.ConfigureAwaitFalseSupported)) { //TODO: Optimize the header size writing. //We skip the first 2 bytes of the payload because it contains the opcode //Which is suppose to be in the header. Therefore we don't wnat to write it twice await DecoratedClient.WriteAsync(((short)payloadBytesCount).Reinterpret(), 0, 2) .ConfigureAwaitFalseVoid(); //We skip the first 2 bytes of the payload because it contains the opcode //Which is suppose to be in the header. Therefore we don't wnat to write it twice await DecoratedClient.WriteAsync(payloadData, offset, payloadBytesCount) .ConfigureAwaitFalseVoid(); } }
private async Task CryptAndSend(byte[] payloadData, int offset, int payloadBytesCount) { //VERY critical we lock here otherwise we could write a header and then another unrelated body could be written inbetween using (await writeSynObj.LockAsync().ConfigureAwait(false)) { //Custom 317 Protocol: //2 byte short payload length. //1 byte opcode (in the payload data). //TODO: Optimize the header size writing. await DecoratedClient.WriteAsync(((short)payloadBytesCount).Reinterpret(), 0, 2) .ConfigureAwait(false); //1 byte opcode is basically type information in the payload data. await DecoratedClient.WriteAsync(payloadData, offset, payloadBytesCount) .ConfigureAwait(false); } }
/// <inheritdoc /> public async Task WriteAsync(TWritePayloadBaseType payload) { //Serializer the payload first so we can build the header byte[] payloadData = Serializer.Serialize(payload); IPacketHeader header = PacketHeaderFactory.Create(payload, payloadData); //VERY critical we lock here otherwise we could write a header and then another unrelated body could be written inbetween using (await writeSynObj.LockAsync().ConfigureAwait(false)) { //It's important to always write the header first await HeaderReaderWriter.WriteHeaderAsync(header) .ConfigureAwait(false); //Write the outgoing message, it will internally create the header and it will be serialized await DecoratedClient.WriteAsync(payloadData) .ConfigureAwait(false); } }
public override async Task WriteAsync(byte[] bytes, int offset, int count) { if (offset < 0) { throw new ArgumentOutOfRangeException(nameof(offset)); } if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count)); } int blocksizeAdjustedCount = ConvertToBlocksizeCount(count); if (count == blocksizeAdjustedCount) { await DecoratedClient.WriteAsync(EncryptionServiceProvider.Crypt(bytes, offset, count), offset, count) .ConfigureAwait(false); } else { //Lock because we use the crypto buffer for this using (await WriteBuffer.BufferLock.LockAsync().ConfigureAwait(false)) { try { //We copy to the thread local buffer so we can use it as an extended buffer by "neededBytes" many more bytes. //So the buffer is very large but we'll tell it to write bytes.length + neededBytes. BufferUtil.QuickUnsafeCopy(bytes, offset, WriteBuffer.Buffer, 0, count); //dont copy full array, might only need less with count } catch (Exception e) { throw new InvalidOperationException($"Failed to copy bytes to crypto buffer. Bytes Length: {bytes.Length} Offset: {offset} Count: {count} BlocksizeAdjustedCount: {blocksizeAdjustedCount}", e); } EncryptionServiceProvider.Crypt(WriteBuffer.Buffer, 0, blocksizeAdjustedCount); //recurr to write the bytes with the now properly sized buffer. await DecoratedClient.WriteAsync(WriteBuffer.Buffer, 0, blocksizeAdjustedCount) .ConfigureAwait(false); } } }
private async Task CryptAndSend(byte[] payloadData, byte[] clientPacketHeader, int payloadBytesOffset, int payloadBytesCount) { //VERY critical we lock here otherwise we could write a header and then another unrelated body could be written inbetween using (await writeSynObj.LockAsync().ConfigureAwait(false)) { //We should check crypto first. If it's init then we need to encrypt the serverPacketHeader if (CryptoService.isInitialized) //TODO: This is a hack, can we fix this? { CryptoService.EncryptionService.ProcessBytes(clientPacketHeader, 0, clientPacketHeader.Length, clientPacketHeader, 0); } //It's important to always write the header first await DecoratedClient.WriteAsync(clientPacketHeader) .ConfigureAwait(false); //We skip the first 2 bytes of the payload because it contains the opcode //Which is suppose to be in the header. Therefore we don't wnat to write it twice await DecoratedClient.WriteAsync(payloadData, 2 + payloadBytesOffset, payloadBytesCount - 2) .ConfigureAwait(false); } }
//TODO: Validate sizes private async Task CryptAndSend(byte[] payloadData, byte[] serverPacketHeader, int payloadDataOffset, int payloadDataCount) { //VERY critical we lock here otherwise we could write a header and then another unrelated body could be written inbetween using (await writeSynObj.LockAsync().ConfigureAwait(false)) { //We should check crypto first. If it's init then we need to encrypt the serverPacketHeader if (CryptoService.isInitialized) { CryptoService.EncryptionService.ProcessBytes(serverPacketHeader, 0, serverPacketHeader.Length, serverPacketHeader, 0); //Encrypt the opcode on the payload data too CryptoService.EncryptionService.ProcessBytes(payloadData, payloadDataOffset, 2, payloadData, payloadDataOffset); } //It's important to always write the header first await DecoratedClient.WriteAsync(serverPacketHeader) .ConfigureAwait(false); await DecoratedClient.WriteAsync(payloadData, payloadDataOffset, payloadDataCount) .ConfigureAwait(false); } }
/// <inheritdoc /> public override async Task WriteAsync(byte[] bytes, int offset, int count) { if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count)); } //If we have more bytes than we require buffering till //we should just write //We have to lock to prevent anything from touching the combined or buffer inbetween using (await BufferedData.BufferLock.LockAsync().ConfigureAwait(false)) using (await CombinedBuffer.BufferLock.LockAsync().ConfigureAwait(false)) { if (count > BufferedData.Buffer.Length && CurrentIndex == -1) { await DecoratedClient.WriteAsync(bytes, offset, count) .ConfigureAwait(false); } else if (count + CurrentIndex + 1 > BufferedData.Buffer.Length && CurrentIndex != -1) { //TODO: Do this somehow without copying BufferUtil.QuickUnsafeCopy(BufferedData.Buffer, 0, CombinedBuffer.Buffer, 0, CurrentIndex + 1); BufferUtil.QuickUnsafeCopy(bytes, offset, CombinedBuffer.Buffer, CurrentIndex + 1, count); await DecoratedClient.WriteAsync(CombinedBuffer.Buffer, 0, count + CurrentIndex + 1) .ConfigureAwait(false); CurrentIndex = -1; } else { //At this point we know that the buffer isn't large enough to write so we need to buffer it BufferUtil.QuickUnsafeCopy(bytes, offset, BufferedData.Buffer, CurrentIndex + 1, count); CurrentIndex += count; } } }
/// <inheritdoc /> public override Task DisconnectAsync(int delay) { return(DecoratedClient.DisconnectAsync(delay)); }
/// <inheritdoc /> public override async Task <int> ReadAsync(byte[] buffer, int start, int count, CancellationToken token) { using (await ReadLock.LockAsync(token).ConfigureAwait(false)) return(await DecoratedClient.ReadAsync(buffer, start, count, token) .ConfigureAwait(false)); }
public override Task <bool> ConnectAsync(string ip, int port) { return(DecoratedClient.ConnectAsync(ip, port)); }
/// <inheritdoc /> public override async Task ClearReadBuffers() { using (await readSynObj.LockAsync().ConfigureAwait(false)) await DecoratedClient.ClearReadBuffers() .ConfigureAwait(false); }
/// <inheritdoc /> public override Task ClearReadBuffers() { return(DecoratedClient.ClearReadBuffers()); }
/// <inheritdoc /> public override async Task ClearReadBuffers() { using (await readSynObj.LockAsync().ConfigureAwait(!GladMMOAsyncSettings.ConfigureAwaitFalseSupported)) await DecoratedClient.ClearReadBuffers() .ConfigureAwaitFalseVoid(); }
/// <inheritdoc /> public override Task WriteAsync(byte[] bytes, int offset, int count) { return(DecoratedClient.WriteAsync(bytes, offset, count)); }
/// <inheritdoc /> public override Task <int> ReadAsync(byte[] buffer, int start, int count, CancellationToken token) { return(DecoratedClient.ReadAsync(buffer, start, count, token)); }
/// <inheritdoc /> public Task WriteAsync(TWritePayloadBaseType payload) { return(DecoratedClient.WriteAsync(payload)); }