Skip to content

feat(dgw): align gateway scans with local planning#1776

Open
irvingouj@Devolutions (irvingoujAtDevolution) wants to merge 1 commit intomasterfrom
feat/network-scan-improvement
Open

feat(dgw): align gateway scans with local planning#1776
irvingouj@Devolutions (irvingoujAtDevolution) wants to merge 1 commit intomasterfrom
feat/network-scan-improvement

Conversation

@irvingoujAtDevolution
Copy link
Copy Markdown
Contributor

@irvingoujAtDevolution irvingouj@Devolutions (irvingoujAtDevolution) commented Apr 30, 2026

Summary

Brings the gateway's /jet/net/scan API closer to feature parity with the local network scanner, so the same scan request shape can drive both.

New query parameters

  • Targets — combinable target=<ip> (single host) and range=<lower>-<upper>. IPv4/IPv6 family validation; rejects ranges over 65 536 addresses with HTTP 400.
  • Source selection — repeatable interface_id=<id> plus range_interface_policy=intersect_selected_interfaces|allow_cross_interface_range. Missing/down/loopback-only/no-scan-capable sources or out-of-interface ranges return a structured 400 ({ error, interfaceId, reason } or { error, ranges, interfaceIds }).
  • Probe controlsenable_tcp_probes=false suppresses all TCP probes regardless of probe=; otherwise probe=22|rdp|https|... sets the probe list.
  • Result togglesreport_ping_status, report_ping_start, report_ping_success, report_ping_failure, report_tcp_failure, include_host_results. The previous enable_failure and enable_ping_start flags remain as deprecated aliases.
  • Concurrencymax_concurrency, max_ping_concurrency, max_tcp_probe_concurrency.
  • Strict bindinterface_bind_strict=true fails the scan if a per-interface socket bind doesn't take effect (default: warn and fall back).

New endpoint

GET /jet/net/interfaces (v2): returns each scan source with a stable id, address, startAddress/endAddress, broadcast address, prefix length, link metadata (MAC, MTU, speed, link type), and per-source capability flags (ipv4, ipv6, subnet, broadcast, zeroConf, tcpProbe, dnsResolve). The id is what interface_id= accepts.

The legacy GET /jet/net/config is retained and now carries RFC 8594 Deprecation: true plus Link: rel="successor-version" headers pointing at /jet/net/interfaces. (No Sunset date until product confirms one.)

New result format

response_format=network_scan_result_v1 opts into a new wire shape:

{ "kind": "host",    "address": "...", "source": "gateway", "discoverySource": "subnet", "isReachable": true,  "hostScanState": "reachable", "responseTimeMs": 7, "interfaceId": "...", "interfaceName": "..." }
{ "kind": "service", "address": "...", "source": "gateway", "discoverySource": "tcp_probe", "isReachable": true, "port": 3389, "serviceLabel": "RDP", "serviceType": "RDP", "responseTimeMs": 12 }

Fields are camelCase with closed lowercase enums (hostScanState ∈ { queued, probing, reachable, unreachable }, discoverySource ∈ { subnet, broadcast, tcp_probe, gateway, zero_conf }). macAddress is in the schema but only populated when neighbor-discovery information is available; it is omitted from the JSON otherwise.

Without the parameter, the legacy event format continues to be emitted unchanged.

Internals

  • Per-interface socket bind for ping and TCP probes on Linux (IP_UNICAST_IF/IPV6_UNICAST_IF), macOS (IP_BOUND_IF/IPV6_BOUND_IF), and Windows (IP_UNICAST_IF). Other targets fail to compile (compile_error!).
  • Event-bus capacity raised to 8192 and TypedReceiver::recv now treats RecvError::Lagged as recoverable (warn-and-continue) instead of terminating its consumer task. This fixes a class of dropouts where a wave of timeouts could starve the forwarder and cause subsequent successful events to be lost.
  • ScannerConfig decomposed into { ports, timing, limits, targeting } sub-structs.
  • Discovered hosts/services emit explicit ServiceReachability and LinkType ADTs instead of bare booleans/strings.

Not included

ARP / NDP-based neighbor discovery is not part of this PR; the API reserves the enable_arp parameter (currently a no-op) so a future change can wire it up without another schema bump.

Test plan

  • cargo +nightly fmt --all -- --check
  • cargo clippy --workspace --tests -- -D warnings
  • cargo test -p network-scanner-proto -p network-scanner-net -p network-scanner --lib
  • cargo test -p devolutions-gateway --lib api
  • Cross-platform target builds — covered by CI

@github-actions
Copy link
Copy Markdown

Let maintainers know that an action is required on their side

  • Add the label release-required Please cut a new release (Devolutions Gateway, Devolutions Agent, Jetsocat, PowerShell module) when you request a maintainer to cut a new release (Devolutions Gateway, Devolutions Agent, Jetsocat, PowerShell module)

  • Add the label release-blocker Follow-up is required before cutting a new release if a follow-up is required before cutting a new release

  • Add the label publish-required Please publish libraries (`Devolutions.Gateway.Utils`, OpenAPI clients, etc) when you request a maintainer to publish libraries (Devolutions.Gateway.Utils, OpenAPI clients, etc.)

  • Add the label publish-blocker Follow-up is required before publishing libraries if a follow-up is required before publishing libraries

@irvingoujAtDevolution irvingouj@Devolutions (irvingoujAtDevolution) changed the title feat(net-scan): align gateway scan API with local scans + ARP/NDP discovery feat(net-scan): align gateway scans with local planning May 1, 2026
@CBenoit
Copy link
Copy Markdown
Member

If I understand correctly, you used Claude to backport the changes made to the net scanner in RDM? Did you notice any improvements?

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates Devolutions Gateway’s network scan API to match the newer “local planning” model from network-scanner, including explicit target/range planning, interface-aware source selection, concurrency controls, and an opt-in v1 websocket result shape while keeping legacy behavior for existing clients.

Changes:

  • Adds /jet/net/interfaces and documents /jet/net/scan (WebSocket handshake) in OpenAPI; marks /jet/net/config as deprecated via response headers.
  • Introduces planning/source inventory and interface-aware execution (including optional interface binding and per-stage concurrency limits) in network-scanner.
  • Refactors scan event filtering/serialization into ScanEventFilter with a configurable response format (legacy vs network_scan_result_v1), and reorganizes unit tests under src/tests/.

Reviewed changes

Copilot reviewed 33 out of 34 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
devolutions-gateway/src/openapi.rs Registers new net scan endpoints/types in the OpenAPI document.
devolutions-gateway/src/api/net.rs Implements new query params, planning validation, /interfaces, scan streaming changes, and deprecates /config.
devolutions-gateway/Cargo.toml Extends openapi feature to include network-scanner/openapi.
crates/network-scanner/src/lib.rs Exposes new modules (planner, results, sources) and mounts in-tree tests.
crates/network-scanner/src/ip_utils.rs Adds IpFamily, single, intersection, address_count, and equality traits to support planning/validation.
crates/network-scanner/src/planner.rs Adds target/range + interface selection planning and structured planning errors.
crates/network-scanner/src/sources.rs Models scan-capable sources with metadata and capability flags; adds system source discovery.
crates/network-scanner/src/scanner.rs Refactors config into timing/limits/targeting; adds interface bind support and injected source providers.
crates/network-scanner/src/task_utils.rs Switches task context creation to use plan_scan output (planned ranges + sources).
crates/network-scanner/src/results.rs Adds ScanEventFilter and v1 result event model + legacy serialization.
crates/network-scanner/src/ping.rs Adds ping queue events, interface binding, and optional concurrency limiting.
crates/network-scanner/src/port_discovery.rs Adds interface binding, optional concurrency limiting, and richer failure classification/time measurement.
crates/network-scanner/src/netbios.rs Adds timing to NetBIOS success events.
crates/network-scanner/src/mdns.rs Adds timing to mDNS resolved events.
crates/network-scanner/src/event_bus.rs Adds AnyScannerEvent wrapper for generic subscriptions; adjusts broadcast match for new shape.
crates/network-scanner/src/broadcast/mod.rs Extends broadcast events with optional timing.
crates/network-scanner/src/broadcast/asynchronous.rs Measures and emits broadcast RTT timing.
crates/network-scanner/examples/scan.rs Updates example for refactored scanner config and targeting controls.
crates/network-scanner/examples/port_discovery.rs Updates example for new scan_ports signature (concurrency + interface bind).
crates/network-scanner/examples/ping_range.rs Updates example for new ping_range signature (concurrency + interface bind).
crates/network-scanner/src/tests/mod.rs Adds src/tests module root for in-tree unit tests.
crates/network-scanner/src/tests/ip_utils.rs Moves/expands unit coverage for IP range utilities.
crates/network-scanner/src/tests/planner.rs Adds unit tests for planning/source selection and policy combinations.
crates/network-scanner/src/tests/results.rs Adds unit tests for legacy/v1 serialization and filter matrix behavior.
crates/network-scanner/src/tests/sources.rs Adds unit tests for source selection/helpers.
crates/network-scanner/src/tests/task_utils.rs Adds unit tests for context planning/execution config mapping.
crates/network-scanner/Cargo.toml Adds serde + optional utoipa feature for OpenAPI schema derivations; adjusts platform deps.
crates/network-scanner-proto/src/lib.rs Adds crate-level docs and mounts in-tree tests module.
crates/network-scanner-proto/src/netbios.rs Moves tests out of module body.
crates/network-scanner-proto/src/tests/mod.rs Adds src/tests module root for proto unit tests.
crates/network-scanner-proto/src/tests/netbios.rs Adds extracted NetBIOS protocol parsing tests.
crates/network-scanner-net/src/socket.rs Adds cross-platform socket interface binding helper.
crates/network-scanner-net/Cargo.toml Adds libc dep for unix setsockopt implementation.
Cargo.lock Updates dependency graph for new features/platform changes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/network-scanner/src/planner.rs
Comment thread crates/network-scanner-proto/src/tests/netbios.rs Outdated
Comment thread crates/network-scanner/src/ip_utils.rs
Comment thread crates/network-scanner/src/netbios.rs
Comment thread crates/network-scanner-net/src/socket.rs Outdated
Comment thread devolutions-gateway/src/api/net.rs Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 34 out of 35 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/network-scanner/src/results.rs
Comment thread crates/network-scanner/src/port_discovery.rs Outdated
@irvingoujAtDevolution irvingouj@Devolutions (irvingoujAtDevolution) force-pushed the feat/network-scan-improvement branch 3 times, most recently from 93723d4 to e333faf Compare May 4, 2026 17:49
@irvingoujAtDevolution
Copy link
Copy Markdown
Contributor Author

irvingouj@Devolutions (irvingoujAtDevolution) commented May 4, 2026

If I understand correctly, you used Claude to backport the changes made to the net scanner in RDM? Did you notice any improvements?

Updated upon request from Paul, mainly to make the request/response shape easier to use on C# side.

Copy link
Copy Markdown
Contributor

@pauldumais Paul Dumais (pauldumais) left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@irvingoujAtDevolution irvingouj@Devolutions (irvingoujAtDevolution) force-pushed the feat/network-scan-improvement branch 5 times, most recently from 268076f to b1b53ee Compare May 4, 2026 19:33
Adds selected network scan sources, explicit target/range planning, interface-aware scan execution, the v1 result format, and gateway API/OpenAPI support while preserving the legacy event format.

ARP/NDP discovery and MAC enrichment are intentionally excluded from this review slice and remain available on backup-feat-network-scan-improvement-with-arp-ndp.
@irvingoujAtDevolution irvingouj@Devolutions (irvingoujAtDevolution) changed the title feat(net-scan): align gateway scans with local planning feat(dgw): align gateway scans with local planning May 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants