Skip to content

Transport silently drops sends to ports outside the configured Port Range, but still arms the APDU timeout #51

Description

@ravz

Summary

If a request targets a UDP port that is not in the gateway's configured Port Range, the transport drops
the datagram with no log — but the APDU timer has already been armed, so the caller gets ERR_TIMEOUT
after the full apduTimeout with nothing on the wire.

That failure signature ("timeout, but Wireshark shows we never sent anything") is very hard to diagnose
from the outside. It came up as a candidate cause while investigating #49; it was not the cause there,
but it is a real bug.

Detail

resources/node-bacstack-ts/dist/lib/transport.js:51-56:

let serverExists = Object.keys(this.serverList).findIndex((existingPort) => port.toString() == existingPort);

if (serverExists !== -1) {
  let server = this.serverList[port];
  server.send(buffer, 0, offset, port, address);
}
// no else — silent drop

serverList is keyed by the ports expanded from the gateway's Port Range matrix
(common.js:99-111). The device port comes from the I-Am source port
(bacnet_device.js:97, via client.js:420), so any device that responds from a port outside the
configured range is permanently unreachable and silent about it.

Meanwhile readProperty (and every other service method) calls _addCallback immediately after
sendBvlc, which arms a setTimeout for apduTimeout (client.js:193-206). Nothing checks whether
the send actually happened.

Verified

Instrumenting the transport and dgram boundaries, with portRangeMatrix: [47808]:

device port 47808 -> MATCH=true   dgram.send 17 bytes   -> ERR_TIMEOUT (no device present)
device port 47809 -> MATCH=false  no dgram.send         -> ERR_TIMEOUT

Identical caller-visible outcome, completely different cause.

Proposed fix

  1. Log on the drop: Cannot send to <address>:<port> — port not in configured Port Range [<bound ports>].
    This alone turns an unexplainable timeout into a one-line diagnosis.
  2. Have Transport.send report failure to its caller (return value or throw) so the service methods can
    fail the request immediately rather than waiting out apduTimeout.
  3. Consider surfacing it in the gateway node status, since it is a configuration error rather than a
    network fault.

Acceptance criteria

  1. A request to a port outside the configured Port Range produces a log line naming the target port and
    the bound ports.
  2. The caller's callback fires promptly with a distinguishable error, not ERR_TIMEOUT after the full
    APDU timeout.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions