Skip to content

Smdn.Net.AddressResolution version 1.0.0-preview3

Pre-release
Pre-release

Choose a tag to compare

@smdn smdn released this 10 Mar 16:54
· 222 commits to main since this release
55b966c

Released package

Release notes

The full release notes are available at gist.

Change log

Change log in this release:

API changes

API changes in this release:
diff --git a/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-net6.0.apilist.cs b/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-net6.0.apilist.cs
index 9e5728f..0fcaecd 100644
--- a/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-net6.0.apilist.cs
+++ b/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-net6.0.apilist.cs
@@ -1,77 +1,77 @@
-// Smdn.Net.AddressResolution.dll (Smdn.Net.AddressResolution-1.0.0-preview2)
+// Smdn.Net.AddressResolution.dll (Smdn.Net.AddressResolution-1.0.0-preview3)
 //   Name: Smdn.Net.AddressResolution
 //   AssemblyVersion: 1.0.0.0
-//   InformationalVersion: 1.0.0-preview2+5edee5ba8620fb382ebb22676635228ad7c81bd2
+//   InformationalVersion: 1.0.0-preview3+b0d0efec19a7bb78ed612cabd93d8e805a1a32f8
 //   TargetFramework: .NETCoreApp,Version=v6.0
 //   Configuration: Release
 //   Referenced assemblies:
 //     Microsoft.Extensions.DependencyInjection.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
 //     Microsoft.Extensions.Logging.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
 //     System.ComponentModel, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
 //     System.Diagnostics.Process, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
 //     System.Linq, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
 //     System.Memory, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
 //     System.Net.NetworkInformation, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
 //     System.Net.Primitives, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
 //     System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
 //     System.Runtime.InteropServices.RuntimeInformation, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
 #nullable enable annotations
 
 using System;
 using System.Net;
 using System.Net.NetworkInformation;
 using System.Threading;
 using System.Threading.Tasks;
 using Microsoft.Extensions.Logging;
 using Smdn.Net.AddressResolution;
 
 namespace Smdn.Net {
   public static class PhysicalAddressExtensions {
     public static string ToMacAddressString(this PhysicalAddress hardwareAddress, char delimiter = ':') {}
   }
 }
 
 namespace Smdn.Net.AddressResolution {
   public interface IAddressResolver<TAddress, TResolvedAddress> {
     ValueTask<TResolvedAddress> ResolveAsync(TAddress address, CancellationToken cancellationToken);
   }
 
   public abstract class MacAddressResolver :
     IAddressResolver<IPAddress, PhysicalAddress>,
     IAddressResolver<PhysicalAddress, IPAddress>,
     IDisposable
   {
     protected static readonly PhysicalAddress AllZeroMacAddress; // = "000000000000"
 
     public static MacAddressResolver Null { get; }
 
     public static MacAddressResolver Create(MacAddressResolverOptions? options = null, IServiceProvider? serviceProvider = null) {}
 
     protected MacAddressResolver(ILogger? logger = null) {}
 
     protected ILogger? Logger { get; }
 
     protected virtual void Dispose(bool disposing) {}
     public void Dispose() {}
     public ValueTask RefreshCacheAsync(CancellationToken cancellationToken = default) {}
     protected virtual ValueTask RefreshCacheAsyncCore(CancellationToken cancellationToken) {}
     public ValueTask<PhysicalAddress?> ResolveIPAddressToMacAddressAsync(IPAddress ipAddress, CancellationToken cancellationToken = default) {}
     protected abstract ValueTask<PhysicalAddress?> ResolveIPAddressToMacAddressAsyncCore(IPAddress ipAddress, CancellationToken cancellationToken);
     public ValueTask<IPAddress?> ResolveMacAddressToIPAddressAsync(PhysicalAddress macAddress, CancellationToken cancellationToken = default) {}
     protected abstract ValueTask<IPAddress?> ResolveMacAddressToIPAddressAsyncCore(PhysicalAddress macAddress, CancellationToken cancellationToken);
     ValueTask<PhysicalAddress?> IAddressResolver<IPAddress, PhysicalAddress>.ResolveAsync(IPAddress address, CancellationToken cancellationToken) {}
     ValueTask<IPAddress?> IAddressResolver<PhysicalAddress, IPAddress>.ResolveAsync(PhysicalAddress address, CancellationToken cancellationToken) {}
     protected void ThrowIfDisposed() {}
   }
 
   public sealed class MacAddressResolverOptions {
     public static readonly MacAddressResolverOptions Default; // = "Smdn.Net.AddressResolution.MacAddressResolverOptions"
 
     public MacAddressResolverOptions() {}
 
     public string? NmapTargetSpecification { get; init; }
     public TimeSpan ProcfsArpScanInterval { get; init; }
   }
 }
 // API list generated by Smdn.Reflection.ReverseGenerating.ListApi.MSBuild.Tasks v1.2.1.0.
 // Smdn.Reflection.ReverseGenerating.ListApi.Core v1.2.0.0 (https://github.com/smdn/Smdn.Reflection.ReverseGenerating)
diff --git a/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-netstandard2.0.apilist.cs b/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-netstandard2.0.apilist.cs
index dc886f6..44fe7a4 100644
--- a/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-netstandard2.0.apilist.cs
+++ b/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-netstandard2.0.apilist.cs
@@ -1,72 +1,72 @@
-// Smdn.Net.AddressResolution.dll (Smdn.Net.AddressResolution-1.0.0-preview2)
+// Smdn.Net.AddressResolution.dll (Smdn.Net.AddressResolution-1.0.0-preview3)
 //   Name: Smdn.Net.AddressResolution
 //   AssemblyVersion: 1.0.0.0
-//   InformationalVersion: 1.0.0-preview2+5edee5ba8620fb382ebb22676635228ad7c81bd2
+//   InformationalVersion: 1.0.0-preview3+b0d0efec19a7bb78ed612cabd93d8e805a1a32f8
 //   TargetFramework: .NETStandard,Version=v2.0
 //   Configuration: Release
 //   Referenced assemblies:
 //     Microsoft.Bcl.AsyncInterfaces, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
 //     Microsoft.Extensions.DependencyInjection.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
 //     Microsoft.Extensions.Logging.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
 //     System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
 //     netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
 #nullable enable annotations
 
 using System;
 using System.Net;
 using System.Net.NetworkInformation;
 using System.Threading;
 using System.Threading.Tasks;
 using Microsoft.Extensions.Logging;
 using Smdn.Net.AddressResolution;
 
 namespace Smdn.Net {
   public static class PhysicalAddressExtensions {
     public static string ToMacAddressString(this PhysicalAddress hardwareAddress, char delimiter = ':') {}
   }
 }
 
 namespace Smdn.Net.AddressResolution {
   public interface IAddressResolver<TAddress, TResolvedAddress> {
     ValueTask<TResolvedAddress> ResolveAsync(TAddress address, CancellationToken cancellationToken);
   }
 
   public abstract class MacAddressResolver :
     IAddressResolver<IPAddress, PhysicalAddress>,
     IAddressResolver<PhysicalAddress, IPAddress>,
     IDisposable
   {
     protected static readonly PhysicalAddress AllZeroMacAddress; // = "000000000000"
 
     public static MacAddressResolver Null { get; }
 
     public static MacAddressResolver Create(MacAddressResolverOptions? options = null, IServiceProvider? serviceProvider = null) {}
 
     protected MacAddressResolver(ILogger? logger = null) {}
 
     protected ILogger? Logger { get; }
 
     protected virtual void Dispose(bool disposing) {}
     public void Dispose() {}
     public ValueTask RefreshCacheAsync(CancellationToken cancellationToken = default) {}
     protected virtual ValueTask RefreshCacheAsyncCore(CancellationToken cancellationToken) {}
     public ValueTask<PhysicalAddress?> ResolveIPAddressToMacAddressAsync(IPAddress ipAddress, CancellationToken cancellationToken = default) {}
     protected abstract ValueTask<PhysicalAddress?> ResolveIPAddressToMacAddressAsyncCore(IPAddress ipAddress, CancellationToken cancellationToken);
     public ValueTask<IPAddress?> ResolveMacAddressToIPAddressAsync(PhysicalAddress macAddress, CancellationToken cancellationToken = default) {}
     protected abstract ValueTask<IPAddress?> ResolveMacAddressToIPAddressAsyncCore(PhysicalAddress macAddress, CancellationToken cancellationToken);
     ValueTask<PhysicalAddress?> IAddressResolver<IPAddress, PhysicalAddress>.ResolveAsync(IPAddress address, CancellationToken cancellationToken) {}
     ValueTask<IPAddress?> IAddressResolver<PhysicalAddress, IPAddress>.ResolveAsync(PhysicalAddress address, CancellationToken cancellationToken) {}
     protected void ThrowIfDisposed() {}
   }
 
   public sealed class MacAddressResolverOptions {
     public static readonly MacAddressResolverOptions Default; // = "Smdn.Net.AddressResolution.MacAddressResolverOptions"
 
     public MacAddressResolverOptions() {}
 
     public string? NmapTargetSpecification { get; init; }
     public TimeSpan ProcfsArpScanInterval { get; init; }
   }
 }
 // API list generated by Smdn.Reflection.ReverseGenerating.ListApi.MSBuild.Tasks v1.2.1.0.
 // Smdn.Reflection.ReverseGenerating.ListApi.Core v1.2.0.0 (https://github.com/smdn/Smdn.Reflection.ReverseGenerating)
diff --git a/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-netstandard2.1.apilist.cs b/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-netstandard2.1.apilist.cs
index 8b48cd3..7ac71b4 100644
--- a/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-netstandard2.1.apilist.cs
+++ b/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-netstandard2.1.apilist.cs
@@ -1,70 +1,70 @@
-// Smdn.Net.AddressResolution.dll (Smdn.Net.AddressResolution-1.0.0-preview2)
+// Smdn.Net.AddressResolution.dll (Smdn.Net.AddressResolution-1.0.0-preview3)
 //   Name: Smdn.Net.AddressResolution
 //   AssemblyVersion: 1.0.0.0
-//   InformationalVersion: 1.0.0-preview2+5edee5ba8620fb382ebb22676635228ad7c81bd2
+//   InformationalVersion: 1.0.0-preview3+b0d0efec19a7bb78ed612cabd93d8e805a1a32f8
 //   TargetFramework: .NETStandard,Version=v2.1
 //   Configuration: Release
 //   Referenced assemblies:
 //     Microsoft.Extensions.DependencyInjection.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
 //     Microsoft.Extensions.Logging.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
 //     netstandard, Version=2.1.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
 #nullable enable annotations
 
 using System;
 using System.Net;
 using System.Net.NetworkInformation;
 using System.Threading;
 using System.Threading.Tasks;
 using Microsoft.Extensions.Logging;
 using Smdn.Net.AddressResolution;
 
 namespace Smdn.Net {
   public static class PhysicalAddressExtensions {
     public static string ToMacAddressString(this PhysicalAddress hardwareAddress, char delimiter = ':') {}
   }
 }
 
 namespace Smdn.Net.AddressResolution {
   public interface IAddressResolver<TAddress, TResolvedAddress> {
     ValueTask<TResolvedAddress> ResolveAsync(TAddress address, CancellationToken cancellationToken);
   }
 
   public abstract class MacAddressResolver :
     IAddressResolver<IPAddress, PhysicalAddress>,
     IAddressResolver<PhysicalAddress, IPAddress>,
     IDisposable
   {
     protected static readonly PhysicalAddress AllZeroMacAddress; // = "000000000000"
 
     public static MacAddressResolver Null { get; }
 
     public static MacAddressResolver Create(MacAddressResolverOptions? options = null, IServiceProvider? serviceProvider = null) {}
 
     protected MacAddressResolver(ILogger? logger = null) {}
 
     protected ILogger? Logger { get; }
 
     protected virtual void Dispose(bool disposing) {}
     public void Dispose() {}
     public ValueTask RefreshCacheAsync(CancellationToken cancellationToken = default) {}
     protected virtual ValueTask RefreshCacheAsyncCore(CancellationToken cancellationToken) {}
     public ValueTask<PhysicalAddress?> ResolveIPAddressToMacAddressAsync(IPAddress ipAddress, CancellationToken cancellationToken = default) {}
     protected abstract ValueTask<PhysicalAddress?> ResolveIPAddressToMacAddressAsyncCore(IPAddress ipAddress, CancellationToken cancellationToken);
     public ValueTask<IPAddress?> ResolveMacAddressToIPAddressAsync(PhysicalAddress macAddress, CancellationToken cancellationToken = default) {}
     protected abstract ValueTask<IPAddress?> ResolveMacAddressToIPAddressAsyncCore(PhysicalAddress macAddress, CancellationToken cancellationToken);
     ValueTask<PhysicalAddress?> IAddressResolver<IPAddress, PhysicalAddress>.ResolveAsync(IPAddress address, CancellationToken cancellationToken) {}
     ValueTask<IPAddress?> IAddressResolver<PhysicalAddress, IPAddress>.ResolveAsync(PhysicalAddress address, CancellationToken cancellationToken) {}
     protected void ThrowIfDisposed() {}
   }
 
   public sealed class MacAddressResolverOptions {
     public static readonly MacAddressResolverOptions Default; // = "Smdn.Net.AddressResolution.MacAddressResolverOptions"
 
     public MacAddressResolverOptions() {}
 
     public string? NmapTargetSpecification { get; init; }
     public TimeSpan ProcfsArpScanInterval { get; init; }
   }
 }
 // API list generated by Smdn.Reflection.ReverseGenerating.ListApi.MSBuild.Tasks v1.2.1.0.
 // Smdn.Reflection.ReverseGenerating.ListApi.Core v1.2.0.0 (https://github.com/smdn/Smdn.Reflection.ReverseGenerating)

Full changes

Full changes in this release:
diff --git a/src/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution.Arp/ProcfsArpNmapScanMacAddressResolver.cs b/src/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution.Arp/ProcfsArpNmapScanMacAddressResolver.cs
index f7144dc..5418064 100644
--- a/src/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution.Arp/ProcfsArpNmapScanMacAddressResolver.cs
+++ b/src/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution.Arp/ProcfsArpNmapScanMacAddressResolver.cs
@@ -1,6 +1,7 @@
 // SPDX-FileCopyrightText: 2022 smdn <smdn@smdn.jp>
 // SPDX-License-Identifier: MIT
 using System;
+using System.Collections.Generic;
 using System.Diagnostics;
 using System.IO;
 using System.Linq;
@@ -48,14 +49,11 @@ internal sealed class ProcfsArpNmapScanMacAddressResolver : ProcfsArpMacAddressR
     // -oG <file>: Output scan in Grepable format
     const string nmapOptions = "-sn -n -T4 -oG - ";
 
-    var outputNmapOutputToTraceLog = Logger is not null && Logger.IsEnabled(LogLevel.Trace);
-    var outputNmapErrorToErrorLog = Logger is not null && Logger.IsEnabled(LogLevel.Error);
-
     var nmapProcessStartInfo = new ProcessStartInfo() {
       FileName = lazyPathToNmap.Value,
       Arguments = nmapOptions + nmapTargetSpecification,
-      RedirectStandardOutput = outputNmapOutputToTraceLog,
-      RedirectStandardError = outputNmapErrorToErrorLog,
+      RedirectStandardOutput = true,
+      RedirectStandardError = true,
       UseShellExecute = false,
     };
 
@@ -78,23 +76,28 @@ internal sealed class ProcfsArpNmapScanMacAddressResolver : ProcfsArpMacAddressR
       nmapProcess.WaitForExit(); // TODO: cacellation
 #endif
 
-      if (outputNmapOutputToTraceLog) {
-        for (
-          var line = await nmapProcess.StandardOutput.ReadLineAsync().ConfigureAwait(false);
-          line is not null;
-          line = await nmapProcess.StandardOutput.ReadLineAsync().ConfigureAwait(false)
-        ) {
-          Logger!.LogTrace("[nmap] {StdOut}", line);
-        }
+      if (Logger is not null) {
+        const LogLevel logLevelForStandardOutput = LogLevel.Trace;
+        const LogLevel logLevelForStandardError = LogLevel.Error;
+
+        static IEnumerable<(StreamReader, LogLevel)> EnumerateLogTarget(StreamReader stdout, StreamReader stderr)
+        {
+          yield return (stdout, logLevelForStandardOutput);
+          yield return (stderr, logLevelForStandardError);
         }
 
-      if (outputNmapErrorToErrorLog) {
-        for (
-          var line = await nmapProcess.StandardError.ReadLineAsync().ConfigureAwait(false);
-          line is not null;
-          line = await nmapProcess.StandardError.ReadLineAsync().ConfigureAwait(false)
-        ) {
-          Logger!.LogError("[nmap] {StdErr}", line);
+        foreach (var (stdio, logLevel) in EnumerateLogTarget(nmapProcess.StandardOutput, nmapProcess.StandardError)) {
+          if (!Logger.IsEnabled(logLevel))
+            continue;
+
+          for (; ;) {
+            var line = await stdio.ReadLineAsync().ConfigureAwait(false);
+
+            if (line is null)
+              break;
+
+            Logger.Log(logLevel, "[nmap] {Line}", line);
+          }
         }
       }
     }
diff --git a/src/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution.csproj b/src/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution.csproj
index 696b5cb..afb36d6 100644
--- a/src/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution.csproj
+++ b/src/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution.csproj
@@ -6,7 +6,7 @@ SPDX-License-Identifier: MIT
   <PropertyGroup>
     <TargetFrameworks>netstandard2.0;netstandard2.1;net6.0</TargetFrameworks>
     <VersionPrefix>1.0.0</VersionPrefix>
-    <VersionSuffix>preview2</VersionSuffix>
+    <VersionSuffix>preview3</VersionSuffix>
     <!-- <PackageValidationBaselineVersion>1.0.0</PackageValidationBaselineVersion> -->
     <Nullable>enable</Nullable>
     <NoWarn>CA1848</NoWarn> <!-- use the LoggerMessage delegates instead -->

Notes

Full Changelog: releases/Smdn.Net.AddressResolution-1.0.0-preview2...releases/Smdn.Net.AddressResolution-1.0.0-preview3