Skip to content

Commit cb93ea2

Browse files
committed
refactor implementation of AcceptSingleSessionAsync()
1 parent 4fa6e56 commit cb93ea2

File tree

1 file changed

+91
-69
lines changed

1 file changed

+91
-69
lines changed

src/Smdn.Net.MuninNode/Smdn.Net.MuninNode/NodeBase.cs

Lines changed: 91 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -201,107 +201,129 @@ public async ValueTask AcceptSingleSessionAsync(
201201
#endif
202202
.ConfigureAwait(false);
203203

204-
IPEndPoint? remoteEndPoint = null;
204+
// holds a reference to the endpoint before the client being disposed
205+
var remoteEndPoint = client.RemoteEndPoint;
205206

206207
try {
207208
cancellationToken.ThrowIfCancellationRequested();
208209

209-
remoteEndPoint = client.RemoteEndPoint as IPEndPoint;
210+
if (!CanAccept(client))
211+
return;
212+
213+
await ProcessSessionAsync(
214+
client,
215+
cancellationToken
216+
).ConfigureAwait(false);
217+
}
218+
finally {
219+
client.Close();
210220

211-
if (remoteEndPoint is null) {
221+
Logger?.LogInformation("[{RemoteEndPoint}] connection closed", remoteEndPoint);
222+
}
223+
224+
bool CanAccept(Socket client)
225+
{
226+
if (client.RemoteEndPoint is not IPEndPoint remoteIPEndPoint) {
212227
Logger?.LogWarning(
213228
"cannot accept {RemoteEndPoint} ({RemoteEndPointAddressFamily})",
214229
client.RemoteEndPoint?.ToString() ?? "(null)",
215230
client.RemoteEndPoint?.AddressFamily
216231
);
217-
return;
232+
233+
return false;
218234
}
219235

220-
if (accessRule is not null && !accessRule.IsAcceptable(remoteEndPoint)) {
221-
Logger?.LogWarning("access refused: {RemoteEndPoint}", remoteEndPoint);
222-
return;
236+
if (accessRule is not null && !accessRule.IsAcceptable(remoteIPEndPoint)) {
237+
Logger?.LogWarning("access refused: {RemoteEndPoint}", remoteIPEndPoint);
238+
239+
return false;
223240
}
224241

225-
var sessionId = GenerateSessionId(server.LocalEndPoint, remoteEndPoint);
242+
return true;
243+
}
244+
}
226245

227-
cancellationToken.ThrowIfCancellationRequested();
246+
private async ValueTask ProcessSessionAsync(
247+
Socket client,
248+
CancellationToken cancellationToken
249+
)
250+
{
251+
cancellationToken.ThrowIfCancellationRequested();
228252

229-
Logger?.LogDebug("[{RemoteEndPoint}] sending banner", remoteEndPoint);
253+
// holds a reference to the endpoint before the client being disposed
254+
var remoteEndPoint = client.RemoteEndPoint;
255+
var sessionId = GenerateSessionId(server!.LocalEndPoint, remoteEndPoint);
230256

231-
try {
232-
await SendResponseAsync(
233-
client,
234-
$"# munin node at {HostName}",
235-
cancellationToken
236-
).ConfigureAwait(false);
237-
}
238-
catch (SocketException ex) when (
239-
ex.SocketErrorCode is
240-
SocketError.Shutdown or // EPIPE (32)
241-
SocketError.ConnectionAborted or // WSAECONNABORTED (10053)
242-
SocketError.OperationAborted or // ECANCELED (125)
243-
SocketError.ConnectionReset // ECONNRESET (104)
244-
) {
245-
Logger?.LogWarning(
246-
"[{RemoteEndPoint}] client closed session while sending banner",
247-
remoteEndPoint
248-
);
257+
Logger?.LogDebug("[{RemoteEndPoint}] sending banner", remoteEndPoint);
249258

250-
return;
251-
}
259+
try {
260+
await SendResponseAsync(
261+
client,
262+
$"# munin node at {HostName}",
263+
cancellationToken
264+
).ConfigureAwait(false);
265+
}
266+
catch (SocketException ex) when (
267+
ex.SocketErrorCode is
268+
SocketError.Shutdown or // EPIPE (32)
269+
SocketError.ConnectionAborted or // WSAECONNABORTED (10053)
270+
SocketError.OperationAborted or // ECANCELED (125)
271+
SocketError.ConnectionReset // ECONNRESET (104)
272+
) {
273+
Logger?.LogWarning(
274+
"[{RemoteEndPoint}] client closed session while sending banner",
275+
remoteEndPoint
276+
);
277+
278+
return;
279+
}
252280
#pragma warning disable CA1031
253-
catch (Exception ex) {
254-
Logger?.LogCritical(
255-
ex,
256-
"[{RemoteEndPoint}] unexpected exception occured while sending banner",
257-
remoteEndPoint
258-
);
281+
catch (Exception ex) {
282+
Logger?.LogCritical(
283+
ex,
284+
"[{RemoteEndPoint}] unexpected exception occured while sending banner",
285+
remoteEndPoint
286+
);
259287

260-
return;
261-
}
288+
return;
289+
}
262290
#pragma warning restore CA1031
263291

264-
cancellationToken.ThrowIfCancellationRequested();
265-
266-
Logger?.LogInformation("[{RemoteEndPoint}] session started; ID={SessionId}", remoteEndPoint, sessionId);
292+
cancellationToken.ThrowIfCancellationRequested();
267293

268-
try {
269-
if (PluginProvider.SessionCallback is not null)
270-
await PluginProvider.SessionCallback.ReportSessionStartedAsync(sessionId, cancellationToken).ConfigureAwait(false);
294+
Logger?.LogInformation("[{RemoteEndPoint}] session started; ID={SessionId}", remoteEndPoint, sessionId);
271295

272-
foreach (var plugin in PluginProvider.Plugins) {
273-
if (plugin.SessionCallback is not null)
274-
await plugin.SessionCallback.ReportSessionStartedAsync(sessionId, cancellationToken).ConfigureAwait(false);
275-
}
296+
try {
297+
if (PluginProvider.SessionCallback is not null)
298+
await PluginProvider.SessionCallback.ReportSessionStartedAsync(sessionId, cancellationToken).ConfigureAwait(false);
276299

277-
// https://docs.microsoft.com/ja-jp/dotnet/standard/io/pipelines
278-
var pipe = new Pipe();
300+
foreach (var plugin in PluginProvider.Plugins) {
301+
if (plugin.SessionCallback is not null)
302+
await plugin.SessionCallback.ReportSessionStartedAsync(sessionId, cancellationToken).ConfigureAwait(false);
303+
}
279304

280-
await Task.WhenAll(
281-
ReceiveCommandAsync(client, remoteEndPoint, pipe.Writer, cancellationToken),
282-
ProcessCommandAsync(client, remoteEndPoint, pipe.Reader, cancellationToken)
283-
).ConfigureAwait(false);
305+
// https://docs.microsoft.com/ja-jp/dotnet/standard/io/pipelines
306+
var pipe = new Pipe();
284307

285-
Logger?.LogInformation("[{RemoteEndPoint}] session closed; ID={SessionId}", remoteEndPoint, sessionId);
286-
}
287-
finally {
288-
foreach (var plugin in PluginProvider.Plugins) {
289-
if (plugin.SessionCallback is not null)
290-
await plugin.SessionCallback.ReportSessionClosedAsync(sessionId, cancellationToken).ConfigureAwait(false);
291-
}
308+
await Task.WhenAll(
309+
ReceiveCommandAsync(client, remoteEndPoint, pipe.Writer, cancellationToken),
310+
ProcessCommandAsync(client, remoteEndPoint, pipe.Reader, cancellationToken)
311+
).ConfigureAwait(false);
292312

293-
if (PluginProvider.SessionCallback is not null)
294-
await PluginProvider.SessionCallback.ReportSessionClosedAsync(sessionId, cancellationToken).ConfigureAwait(false);
295-
}
313+
Logger?.LogInformation("[{RemoteEndPoint}] session closed; ID={SessionId}", remoteEndPoint, sessionId);
296314
}
297315
finally {
298-
client.Close();
316+
foreach (var plugin in PluginProvider.Plugins) {
317+
if (plugin.SessionCallback is not null)
318+
await plugin.SessionCallback.ReportSessionClosedAsync(sessionId, cancellationToken).ConfigureAwait(false);
319+
}
299320

300-
Logger?.LogInformation("[{RemoteEndPoint}] connection closed", remoteEndPoint);
321+
if (PluginProvider.SessionCallback is not null)
322+
await PluginProvider.SessionCallback.ReportSessionClosedAsync(sessionId, cancellationToken).ConfigureAwait(false);
301323
}
302324
}
303325

304-
private static string GenerateSessionId(EndPoint? localEndPoint, IPEndPoint remoteEndPoint)
326+
private static string GenerateSessionId(EndPoint? localEndPoint, EndPoint? remoteEndPoint)
305327
{
306328
#if SYSTEM_SECURITY_CRYPTOGRAPHY_SHA1_HASHSIZEINBYTES
307329
const int SHA1HashSizeInBytes = SHA1.HashSizeInBytes;
@@ -328,7 +350,7 @@ private static string GenerateSessionId(EndPoint? localEndPoint, IPEndPoint remo
328350

329351
private async Task ReceiveCommandAsync(
330352
Socket socket,
331-
IPEndPoint remoteEndPoint,
353+
EndPoint? remoteEndPoint,
332354
PipeWriter writer,
333355
CancellationToken cancellationToken
334356
)
@@ -406,7 +428,7 @@ ex.SocketErrorCode is
406428

407429
private async Task ProcessCommandAsync(
408430
Socket socket,
409-
IPEndPoint remoteEndPoint,
431+
EndPoint? remoteEndPoint,
410432
PipeReader reader,
411433
CancellationToken cancellationToken
412434
)

0 commit comments

Comments
 (0)