feat(dgw): align gateway scans with local planning#1776
feat(dgw): align gateway scans with local planning#1776irvingouj@Devolutions (irvingoujAtDevolution) wants to merge 1 commit intomasterfrom
Conversation
Let maintainers know that an action is required on their side
|
f5e9736 to
eb59efa
Compare
eb59efa to
d0ef8ab
Compare
|
If I understand correctly, you used Claude to backport the changes made to the net scanner in RDM? Did you notice any improvements? |
There was a problem hiding this comment.
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/interfacesand documents/jet/net/scan(WebSocket handshake) in OpenAPI; marks/jet/net/configas 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
ScanEventFilterwith a configurable response format (legacyvsnetwork_scan_result_v1), and reorganizes unit tests undersrc/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.
d0ef8ab to
4b15f5b
Compare
e6e838c to
176fcb6
Compare
There was a problem hiding this comment.
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.
93723d4 to
e333faf
Compare
Updated upon request from Paul, mainly to make the request/response shape easier to use on C# side. |
268076f to
b1b53ee
Compare
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.
b1b53ee to
4ab4331
Compare
Summary
Brings the gateway's
/jet/net/scanAPI closer to feature parity with the local network scanner, so the same scan request shape can drive both.New query parameters
target=<ip>(single host) andrange=<lower>-<upper>. IPv4/IPv6 family validation; rejects ranges over 65 536 addresses with HTTP 400.interface_id=<id>plusrange_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 }).enable_tcp_probes=falsesuppresses all TCP probes regardless ofprobe=; otherwiseprobe=22|rdp|https|...sets the probe list.report_ping_status,report_ping_start,report_ping_success,report_ping_failure,report_tcp_failure,include_host_results. The previousenable_failureandenable_ping_startflags remain as deprecated aliases.max_concurrency,max_ping_concurrency,max_tcp_probe_concurrency.interface_bind_strict=truefails 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 stableid, 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). Theidis whatinterface_id=accepts.The legacy
GET /jet/net/configis retained and now carries RFC 8594Deprecation: trueplusLink: rel="successor-version"headers pointing at/jet/net/interfaces. (NoSunsetdate until product confirms one.)New result format
response_format=network_scan_result_v1opts 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 }).macAddressis 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
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!).TypedReceiver::recvnow treatsRecvError::Laggedas 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.ScannerConfigdecomposed into{ ports, timing, limits, targeting }sub-structs.ServiceReachabilityandLinkTypeADTs instead of bare booleans/strings.Not included
ARP / NDP-based neighbor discovery is not part of this PR; the API reserves the
enable_arpparameter (currently a no-op) so a future change can wire it up without another schema bump.Test plan
cargo +nightly fmt --all -- --checkcargo clippy --workspace --tests -- -D warningscargo test -p network-scanner-proto -p network-scanner-net -p network-scanner --libcargo test -p devolutions-gateway --lib api