Skip to content

Commit 35ac741

Browse files
committed
reduce allocations by SessionId hex conversion
generate the hex string once instead of every log call and optimize ToHex().
1 parent 5a5770d commit 35ac741

File tree

2 files changed

+47
-34
lines changed

2 files changed

+47
-34
lines changed

src/Renci.SshNet/Security/KeyExchange.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ public Cipher CreateServerCipher(out bool isAead)
198198
serverKey = GenerateSessionKey(SharedKey, ExchangeHash, serverKey, _serverCipherInfo.KeySize / 8);
199199

200200
_logger.LogInformation("[{SessionId}] Creating {ServerEncryption} server cipher.",
201-
Session.ToHex(Session.SessionId),
201+
Session.SessionIdHex,
202202
Session.ConnectionInfo.CurrentServerEncryption);
203203

204204
// Create server cipher
@@ -226,7 +226,7 @@ public Cipher CreateClientCipher(out bool isAead)
226226
clientKey = GenerateSessionKey(SharedKey, ExchangeHash, clientKey, _clientCipherInfo.KeySize / 8);
227227

228228
_logger.LogInformation("[{SessionId}] Creating {ClientEncryption} client cipher.",
229-
Session.ToHex(Session.SessionId),
229+
Session.SessionIdHex,
230230
Session.ConnectionInfo.CurrentClientEncryption);
231231

232232
// Create client cipher
@@ -259,7 +259,7 @@ public HashAlgorithm CreateServerHash(out bool isEncryptThenMAC)
259259
_serverHashInfo.KeySize / 8);
260260

261261
_logger.LogInformation("[{SessionId}] Creating {ServerHmacAlgorithm} server hmac algorithm.",
262-
Session.ToHex(Session.SessionId),
262+
Session.SessionIdHex,
263263
Session.ConnectionInfo.CurrentServerHmacAlgorithm);
264264

265265
return _serverHashInfo.HashAlgorithm(serverKey);
@@ -291,7 +291,7 @@ public HashAlgorithm CreateClientHash(out bool isEncryptThenMAC)
291291
_clientHashInfo.KeySize / 8);
292292

293293
_logger.LogInformation("[{SessionId}] Creating {ClientHmacAlgorithm} client hmac algorithm.",
294-
Session.ToHex(Session.SessionId),
294+
Session.SessionIdHex,
295295
Session.ConnectionInfo.CurrentClientHmacAlgorithm);
296296

297297
return _clientHashInfo.HashAlgorithm(clientKey);
@@ -311,7 +311,7 @@ public Compressor CreateCompressor()
311311
}
312312

313313
_logger.LogInformation("[{SessionId}] Creating {CompressionAlgorithm} client compressor.",
314-
Session.ToHex(Session.SessionId),
314+
Session.SessionIdHex,
315315
Session.ConnectionInfo.CurrentClientCompressionAlgorithm);
316316

317317
var compressor = _compressorFactory();
@@ -335,7 +335,7 @@ public Compressor CreateDecompressor()
335335
}
336336

337337
_logger.LogInformation("[{SessionId}] Creating {ServerCompressionAlgorithm} server decompressor.",
338-
Session.ToHex(Session.SessionId),
338+
Session.SessionIdHex,
339339
Session.ConnectionInfo.CurrentServerCompressionAlgorithm);
340340

341341
var decompressor = _decompressorFactory();

src/Renci.SshNet/Session.cs

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
using System.Linq;
66
using System.Net.Sockets;
77
using System.Security.Cryptography;
8+
#if !NET
89
using System.Text;
10+
#endif
911
using System.Threading;
1012
using System.Threading.Tasks;
1113

@@ -291,13 +293,28 @@ public bool IsConnected
291293
}
292294
}
293295

296+
private byte[] _sessionId;
297+
294298
/// <summary>
295299
/// Gets the session id.
296300
/// </summary>
297301
/// <value>
298302
/// The session id, or <see langword="null"/> if the client has not been authenticated.
299303
/// </value>
300-
public byte[] SessionId { get; private set; }
304+
public byte[] SessionId
305+
{
306+
get
307+
{
308+
return _sessionId;
309+
}
310+
private set
311+
{
312+
_sessionId = value;
313+
SessionIdHex = ToHex(value);
314+
}
315+
}
316+
317+
internal string SessionIdHex { get; private set; }
301318

302319
/// <summary>
303320
/// Gets the client init message.
@@ -800,7 +817,7 @@ public async Task ConnectAsync(CancellationToken cancellationToken)
800817
/// </remarks>
801818
public void Disconnect()
802819
{
803-
_logger.LogInformation("[{SessionId}] Disconnecting session.", ToHex(SessionId));
820+
_logger.LogInformation("[{SessionId}] Disconnecting session.", SessionIdHex);
804821

805822
// send SSH_MSG_DISCONNECT message, clear socket read buffer and dispose it
806823
Disconnect(DisconnectReason.ByApplication, "Connection terminated by the client.");
@@ -1030,7 +1047,7 @@ internal void SendMessage(Message message)
10301047
WaitOnHandle(_keyExchangeCompletedWaitHandle.WaitHandle);
10311048
}
10321049

1033-
_logger.LogInformation("[{SessionId}] Sending message '{MessageType}' to server: '{Message}'.", ToHex(SessionId), message.GetType().Name, message);
1050+
_logger.LogInformation("[{SessionId}] Sending message '{MessageType}' to server: '{Message}'.", SessionIdHex, message.GetType().Name, message);
10341051

10351052
var paddingMultiplier = _clientCipher is null ? (byte)8 : Math.Max((byte)8, _clientCipher.MinimumSize);
10361053
var packetData = message.GetPacket(paddingMultiplier, _clientCompression, _clientEtm || _clientAead);
@@ -1384,7 +1401,7 @@ private void TrySendDisconnect(DisconnectReason reasonCode, string message)
13841401
/// <param name="message"><see cref="DisconnectMessage"/> message.</param>
13851402
internal void OnDisconnectReceived(DisconnectMessage message)
13861403
{
1387-
_logger.LogInformation("[{SessionId}] Disconnect received: {ReasonCode} {MessageDescription}.", ToHex(SessionId), message.ReasonCode, message.Description);
1404+
_logger.LogInformation("[{SessionId}] Disconnect received: {ReasonCode} {MessageDescription}.", SessionIdHex, message.ReasonCode, message.Description);
13881405

13891406
// transition to disconnecting state to avoid throwing exceptions while cleaning up, and to
13901407
// ensure any exceptions that are raised do not overwrite the SshConnectionException that we
@@ -1479,7 +1496,7 @@ internal void OnKeyExchangeInitReceived(KeyExchangeInitMessage message)
14791496
{
14801497
_isStrictKex = true;
14811498

1482-
_logger.LogInformation("[{SessionId}] Enabling strict key exchange extension.", ToHex(SessionId));
1499+
_logger.LogInformation("[{SessionId}] Enabling strict key exchange extension.", SessionIdHex);
14831500

14841501
if (_inboundPacketSequence != 1)
14851502
{
@@ -1495,7 +1512,7 @@ internal void OnKeyExchangeInitReceived(KeyExchangeInitMessage message)
14951512

14961513
ConnectionInfo.CurrentKeyExchangeAlgorithm = _keyExchange.Name;
14971514

1498-
_logger.LogInformation("[{SessionId}] Performing {KeyExchangeAlgorithm} key exchange.", ToHex(SessionId), ConnectionInfo.CurrentKeyExchangeAlgorithm);
1515+
_logger.LogInformation("[{SessionId}] Performing {KeyExchangeAlgorithm} key exchange.", SessionIdHex, ConnectionInfo.CurrentKeyExchangeAlgorithm);
14991516

15001517
_keyExchange.HostKeyReceived += KeyExchange_HostKeyReceived;
15011518

@@ -1811,34 +1828,30 @@ private Message LoadMessage(byte[] data, int offset, int count)
18111828
var message = _sshMessageFactory.Create(messageType);
18121829
message.Load(data, offset + 1, count - 1);
18131830

1814-
_logger.LogInformation("[{SessionId}] Received message '{MessageType}' from server: '{Message}'.", ToHex(SessionId), message.GetType().Name, message);
1831+
_logger.LogInformation("[{SessionId}] Received message '{MessageType}' from server: '{Message}'.", SessionIdHex, message.GetType().Name, message);
18151832

18161833
return message;
18171834
}
18181835

1819-
private static string ToHex(byte[] bytes, int offset)
1836+
private static string ToHex(byte[] bytes)
18201837
{
1821-
var byteCount = bytes.Length - offset;
1822-
1823-
var builder = new StringBuilder(bytes.Length * 2);
1824-
1825-
for (var i = offset; i < byteCount; i++)
1838+
if (bytes is null)
18261839
{
1827-
var b = bytes[i];
1828-
_ = builder.Append(b.ToString("X2"));
1840+
return null;
18291841
}
18301842

1831-
return builder.ToString();
1832-
}
1843+
#if NET
1844+
return Convert.ToHexString(bytes);
1845+
#else
1846+
var builder = new StringBuilder(bytes.Length * 2);
18331847

1834-
internal static string ToHex(byte[] bytes)
1835-
{
1836-
if (bytes is null)
1848+
foreach (var b in bytes)
18371849
{
1838-
return null;
1850+
builder.Append(b.ToString("X2"));
18391851
}
18401852

1841-
return ToHex(bytes, 0);
1853+
return builder.ToString();
1854+
#endif
18421855
}
18431856

18441857
/// <summary>
@@ -1955,7 +1968,7 @@ private void SocketDisconnectAndDispose()
19551968
{
19561969
try
19571970
{
1958-
_logger.LogInformation("[{SessionId}] Shutting down socket.", ToHex(SessionId));
1971+
_logger.LogInformation("[{SessionId}] Shutting down socket.", SessionIdHex);
19591972

19601973
// Interrupt any pending reads; should be done outside of socket read lock as we
19611974
// actually want shutdown the socket to make sure blocking reads are interrupted.
@@ -1971,9 +1984,9 @@ private void SocketDisconnectAndDispose()
19711984
}
19721985
}
19731986

1974-
_logger.LogInformation("[{SessionId}] Disposing socket.", ToHex(SessionId));
1987+
_logger.LogInformation("[{SessionId}] Disposing socket.", SessionIdHex);
19751988
_socket.Dispose();
1976-
_logger.LogInformation("[{SessionId}] Disposed socket.", ToHex(SessionId));
1989+
_logger.LogInformation("[{SessionId}] Disposed socket.", SessionIdHex);
19771990
_socket = null;
19781991
}
19791992
}
@@ -2057,7 +2070,7 @@ private void RaiseError(Exception exp)
20572070
{
20582071
var connectionException = exp as SshConnectionException;
20592072

2060-
_logger.LogInformation(exp, "[{SessionId}] Raised exception", ToHex(SessionId));
2073+
_logger.LogInformation(exp, "[{SessionId}] Raised exception", SessionIdHex);
20612074

20622075
if (_isDisconnecting)
20632076
{
@@ -2084,7 +2097,7 @@ private void RaiseError(Exception exp)
20842097

20852098
if (connectionException != null)
20862099
{
2087-
_logger.LogInformation(exp, "[{SessionId}] Disconnecting after exception", ToHex(SessionId));
2100+
_logger.LogInformation(exp, "[{SessionId}] Disconnecting after exception", SessionIdHex);
20882101
Disconnect(connectionException.DisconnectReason, exp.ToString());
20892102
}
20902103
}
@@ -2157,7 +2170,7 @@ protected virtual void Dispose(bool disposing)
21572170

21582171
if (disposing)
21592172
{
2160-
_logger.LogInformation("[{SessionId}] Disposing session.", ToHex(SessionId));
2173+
_logger.LogInformation("[{SessionId}] Disposing session.", SessionIdHex);
21612174

21622175
Disconnect();
21632176

0 commit comments

Comments
 (0)