Skip to content

v2.0.0

Latest

Choose a tag to compare

@hekkaaa hekkaaa released this 11 Sep 12:55
87bfc42

Changelog

All notable changes to NetObserver are documented in this file.
For the Russian version, see CHANGELOG.ru.md.

[2.0.0] — Bug fixes, retarget to .NET Standard 2.1, and internal cleanup

This release addresses a set of real bugs found in the original 1.1.3 codebase (netstandard2.0), reduces
duplicated code, and moves the target framework forward. The public API surface is backward compatible:
existing consumers calling LocalIp, DnsInfo, IcmpRequestSender(Async), PingClassic(Async),
Traceroute(Async), and the synchronous OpenPort.GetOpenPort(...) overloads should not need to change any
call sites. New async overloads were added additively.

Fixed

  • LocalIp accumulated stale results across calls. The class used private static List<...> fields that
    were never cleared. Calling GetIpv4Localhost() or GetAllIpv4NetInterface() more than once could return
    addresses left over from a previous call (and was not thread-safe). Rewritten to build a fresh, local list on
    every call — nothing is cached or shared between calls anymore.
  • OpenPort could leak a pending connection attempt on timeout. The original code used the legacy
    BeginConnect/EndConnect pattern and called Socket.Close() on timeout without ever calling EndConnect,
    so a connection completing after the timeout could throw in the background after the socket was already
    disposed. Rewritten around TcpClient.ConnectAsync + Task.WhenAny, with the (possibly still pending)
    connect task's eventual exception explicitly observed, so it never surfaces as an unobserved task exception.
  • Lost stack traces when translating exceptions. Every ping/DNS/traceroute method re-threw caught
    exceptions using new SomeException(message, ex.InnerException) — passing the inner exception (frequently
    null) instead of the exception that was actually caught (ex). The original stack trace was discarded.
    Centralized into Common/ExceptionHelper, which always chains the true original exception, so
    Exception.InnerException / .ToString() now show the real failure point.
  • Misused ArgumentNullException/ArgumentOutOfRangeException constructors in a few call sites (passing a
    human-readable message where the API expects a parameter name, or vice-versa) — fixed via the same helper.
  • Hardcoded, machine-local absolute path in NetObserver.csproj
    (..\..\..\..\Users\Laise\Downloads\IconsPacket.png) pointed at the original author's local Downloads
    folder. Anyone else cloning the repository would fail to build the NuGet package (or silently lose the
    package icon). Fixed to reference Resources\IconsPacket.png, which already ships in the repository.

Changed

  • Target framework: netstandard2.0 → netstandard2.1.
  • EnableNETAnalyzers turned back on (it was explicitly disabled in the original project, which likely hid
    some of the issues above from the IDE/build).
  • LocalIp and DnsInfo are now static class (they only ever exposed static members; this prevents
    meaningless instantiation). Minor breaking change if any consumer did new LocalIp() / new DnsInfo()
    — unlikely, since none of their members were instance members.
  • Traceroute / TracerouteAsync: the _buffer field is now static readonly instead of a mutable instance
    field; the max-TTL default (previously inconsistently 31 in Traceroute vs. 30 in TracerouteAsync) is
    now 30 in both.
  • Reduced duplication:
    • IcmpRequestSender / IcmpRequestSenderAsync: the five nearly-identical catch blocks per overload were
      replaced by a single call into Common/ExceptionHelper.
    • Traceroute / TracerouteAsync: the four public overloads now delegate to two private core methods
      (TraceRouteCore(Async) / DetailTraceRouteCore(Async)) instead of duplicating the hop-walking loop.
    • LocalIp: four nearly-identical private methods collapsed into one, parameterized by PrefixOrigin.

Added

  • OpenPort.GetOpenPortAsync(...) — async, cancellable single-port and port-range scanning, with a
    maxConcurrency parameter (default 200) that bounds how many ports are probed in parallel, instead of the
    original's fully sequential range scan (which could block for minutes on wide ranges).
  • XML doc comments clarified/expanded, including an explicit note on GetDetailTraceRoute(Async) explaining
    why it sends a second, direct ping per hop (to get a normal PingReply — round-trip time, buffer, and a
    Success status — instead of exposing the raw TtlExpired reply). This was flagged in review as possibly
    redundant, but removing it would have changed observable behavior (and broken the existing
    GetDetailTraceRouteTest, which asserts Status == Success on every hop), so it was kept and documented
    instead of "fixed".

Compatibility note

netstandard2.1 is not supported by classic .NET Framework (4.x) — only .NET Core 3.0+, .NET 5+, and
recent Mono/Xamarin. If your consumers are still on .NET Framework, this release are not
suitable; stay on 1.1.x or ask for a netstandard2.0 + netstandard2.1/net10.0 multi-target build.


[1.1.3] and earlier

Original releases by the upstream author, targeting netstandard2.0. See the project's GitHub history for
details predating this fork/rewrite.

What's Changed

Full Changelog: v1.1.3...v2.0.0