Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/Renci.SshNet/Abstractions/ArrayExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#nullable enable
#if !NET

namespace System
{
internal static class ArrayExtensions
{
extension(Array)
{
internal static int MaxLength
{
get { return 0X7FFFFFC7; }
}
}
}
}
#endif
50 changes: 0 additions & 50 deletions src/Renci.SshNet/Abstractions/SocketAbstraction.Async.cs

This file was deleted.

55 changes: 37 additions & 18 deletions src/Renci.SshNet/Abstractions/SocketExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,6 @@ public static Task ConnectAsync(this Socket socket, EndPoint remoteEndpoint, Can
return connectTask.IsCompleted || !cancellationToken.CanBeCanceled
? connectTask
: WaitWithCancellation(connectTask, socket, cancellationToken);

static async Task WaitWithCancellation(Task connectTask, Socket socket, CancellationToken cancellationToken)
{
using (cancellationToken.Register(static s => ((Socket)s).Dispose(), socket, useSynchronizationContext: false))
{
await connectTask.ConfigureAwait(false);
}
}
}

public static Task<int> ReceiveAsync(this Socket socket, byte[] buffer, CancellationToken cancellationToken)
{
return ReceiveAsync(socket, buffer, 0, buffer.Length, cancellationToken);
}

public static Task<int> ReceiveAsync(this Socket socket, byte[] buffer, int offset, int length, CancellationToken cancellationToken)
Expand All @@ -58,13 +45,45 @@ public static Task<int> ReceiveAsync(this Socket socket, byte[] buffer, int offs
return receiveTask.IsCompleted || !cancellationToken.CanBeCanceled
? receiveTask
: WaitWithCancellation(receiveTask, socket, cancellationToken);
}

public static Task<int> SendAsync(this Socket socket, byte[] buffer, CancellationToken cancellationToken)
{
return SendAsync(socket, buffer, 0, buffer.Length, cancellationToken);
}

public static Task<int> SendAsync(this Socket socket, byte[] buffer, int offset, int length, CancellationToken cancellationToken)
{
if (cancellationToken.IsCancellationRequested)
{
return Task.FromCanceled<int>(cancellationToken);
}

var sendTask = Task.Factory.FromAsync(
static (s, buffer, callback, state) => s.BeginSend(buffer.Array, buffer.Offset, buffer.Count, SocketFlags.None, callback, state),
static result => ((Socket)result.AsyncState).EndSend(result),
socket,
new ArraySegment<byte>(buffer, offset, length),
state: socket);

return sendTask.IsCompleted || !cancellationToken.CanBeCanceled
? sendTask
: WaitWithCancellation(sendTask, socket, cancellationToken);
}

static async Task<int> WaitWithCancellation(Task<int> receiveTask, Socket socket, CancellationToken cancellationToken)
private static async Task WaitWithCancellation(Task task, Socket socket, CancellationToken cancellationToken)
{
using (cancellationToken.Register(static s => ((Socket)s).Dispose(), socket, useSynchronizationContext: false))
{
await task.ConfigureAwait(false);
}
}

private static async Task<int> WaitWithCancellation(Task<int> task, Socket socket, CancellationToken cancellationToken)
{
using (cancellationToken.Register(static s => ((Socket)s).Dispose(), socket, useSynchronizationContext: false))
{
using (cancellationToken.Register(static s => ((Socket)s).Dispose(), socket, useSynchronizationContext: false))
{
return await receiveTask.ConfigureAwait(false);
}
return await task.ConfigureAwait(false);
}
}
}
Expand Down
24 changes: 11 additions & 13 deletions src/Renci.SshNet/Common/ArrayBuffer.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#pragma warning disable
// Copied verbatim from https://github.com/dotnet/runtime/blob/d2650b6ae7023a2d9d2c74c56116f1f18472ab04/src/libraries/Common/src/System/Net/ArrayBuffer.cs
// Copied verbatim from https://github.com/dotnet/runtime/blob/591622c69134f9a790f902e364c7a6a5c572b12d/src/libraries/Common/src/System/Net/ArrayBuffer.cs

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
Expand All @@ -24,12 +24,6 @@ namespace System.Net
[StructLayout(LayoutKind.Auto)]
internal struct ArrayBuffer : IDisposable
{
#if NET
private static int ArrayMaxLength => Array.MaxLength;
#else
private const int ArrayMaxLength = 0X7FFFFFC7;
#endif

private readonly bool _usePool;
private byte[] _bytes;
private int _activeStart;
Expand Down Expand Up @@ -62,8 +56,7 @@ public ArrayBuffer(byte[] buffer)

public void Dispose()
{
_activeStart = 0;
_availableStart = 0;
DiscardAll();

byte[] array = _bytes;
_bytes = null!;
Expand All @@ -80,8 +73,7 @@ public void ClearAndReturnBuffer()
Debug.Assert(_usePool);
Debug.Assert(_bytes is not null);

_activeStart = 0;
_availableStart = 0;
DiscardAll();

byte[] bufferToReturn = _bytes;
_bytes = Array.Empty<byte>();
Expand Down Expand Up @@ -115,6 +107,12 @@ public void Discard(int byteCount)
}
}

public void DiscardAll()
{
_activeStart = 0;
_availableStart = 0;
}

public void Commit(int byteCount)
{
Debug.Assert(byteCount <= AvailableLength);
Expand Down Expand Up @@ -155,13 +153,13 @@ private void EnsureAvailableSpaceCore(int byteCount)

int desiredSize = ActiveLength + byteCount;

if ((uint)desiredSize > ArrayMaxLength)
if ((uint)desiredSize > Array.MaxLength)
{
throw new OutOfMemoryException();
}

// Double the existing buffer size (capped at Array.MaxLength).
int newSize = Math.Max(desiredSize, (int)Math.Min(ArrayMaxLength, 2 * (uint)_bytes.Length));
int newSize = Math.Max(desiredSize, (int)Math.Min(Array.MaxLength, 2 * (uint)_bytes.Length));

byte[] newBytes = _usePool ?
ArrayPool<byte>.Shared.Rent(newSize) :
Expand Down
17 changes: 9 additions & 8 deletions src/Renci.SshNet/Common/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
#if !NET
using System.Text;
#endif
using System.Threading;

using Renci.SshNet.Messages;
Expand Down Expand Up @@ -419,14 +422,6 @@ async Task<T> WaitCore()
}
}

extension(Array)
{
internal static int MaxLength
{
get { return 0X7FFFFFC7; }
}
}

extension(Task t)
{
internal bool IsCompletedSuccessfully
Expand Down Expand Up @@ -460,5 +455,11 @@ public static bool TryComputeHash(
return true;
#endif
}
#if !NET
internal static string GetString(this Encoding encoding, ReadOnlySpan<byte> bytes)
{
return encoding.GetString(bytes.ToArray());
}
#endif
}
}
36 changes: 0 additions & 36 deletions src/Renci.SshNet/Connection/IProtocolVersionExchange.cs

This file was deleted.

Loading