Versioning
The underlying Rust library follows the semantic versioning specification. Refer to the specification for the meaning of the <major>.<minor>.<patch>
fields of the version number when using the library in Rust.
Version numbers
The following sections describe the meaning of the fields in the version number.
Major
Major releases are for substantial breaking changes and should occur infrequently. They provide an opportunity to consolidate functionality that may have been added in an ad hoc manner in support of backwards compatibility in minor releases. Major releases may also add functionality that requires refactoring of the API.
Minor
Minor releases are for introducing new functionality in a (mostly) backwards compatible manner:
- Rust - API compatible per
semver - C & C++ - API compatible
- Java - API compatible
- .NET - API compatible with the exception that we may add new methods to interfaces that need to be stubbed out
C++, Java, Rust, and even C (via NULL) support a way of defining default methods on interfaces. This allows us to extend interfaces in minor releases without breaking source compatibility in these languages. .NET needs .NET Standard 2.1 for default interface methods, which .NET Framework doesn't support, so the bindings target .NET Standard 2.0 and can't use them. Version 2.0 will target .NET Standard 2.1 and drop .NET Framework, which removes this exception.
Patch
Patch releases are only for fixing bugs that cannot wait for a minor release to be resolved. Patch releases, e.g. 1.0.0 -> 1.0.1, are API compatible in all languages. The C library (libdnp3_ffi.so) will also be ABI compatible between patch versions.
The latest release (version 1.8.0-RC1) is available here.Changelog
1.8.0
- 🛡️ Hardened against panics. Lints deny common sources of panics throughout the core library, and CI now proves that important parts of it can't panic for any input.
- 🔔 License update. The license now prohibits using the library to build or test other implementations of the protocol, including by mining it with AI tools or using it as an oracle, and reserves AI training. See #712.
- 🔔 The minimum supported Rust version is now 1.88. See #502.
- 🔔 Binary output status points default to g10v2 instead of g10v1, in Rust and in the bindings. See #853.
- 🔔
RetryStrategyraises a delay of zero to 1 ms and swaps a reversed minimum and maximum. See #570. - 🔔 Defining a string device attribute longer than 255 bytes fails with the new
AttrDefError::BadValue. See #567. - 🔔 Deprecate
WriteError::IinError,TimeSyncError::IinError,TimeSyncError::SystemTimeNotUnix,CommandResponseError::RequestandObjectParseError::UnsupportedQualifierCode, which are never returned. They will be removed in 2.0. See #556. - 🔔 Tasks whose response objects can't be parsed fail with
MalformedResponse. See #696 and #702. - 🔔 Outstations answer a read of a point type that has no points with IIN2.1, and a range read that includes missing points with IIN2.2 while still returning the points that exist, as the standard requires. Masters that poll types or ranges the outstation doesn't have will see these errors where they saw none before. See #487.
- 🔔 Outstations report a counter, frozen counter or analog input that isn't simply ONLINE in a variation with flags, even when the master asked for one without, so a response can mix the two. See #484.
- 🔔 Outstations report events recorded without time in variations without time, and binary and double-bit input events recorded while unsynchronized with relative time. See #744 and #646.
- 🔔 Analog values: adding a point with a NaN or negative deadband fails, and NaN values, deadbands and commands are handled as the standard requires. See #551, #649, #650, #651 and #652.
- 🔔 The master processes responses that set IIN2 error bits instead of discarding them, and no longer confirms unsolicited responses it can't parse. See #536, #554 and #598.
- 🔔 The master confirms the response to any request when the outstation asks for a confirmation. See #689.
- 🔔 The master's automatic time sync runs before the integrity scan at startup and after a restart. See #708.
- 🔔 File and directory reads that end early send one CLOSE, and fail with the cause. See #621 and #626.
- 🔔 Expected traffic, such as frames for other outstations and repeated segments, is logged at debug instead of warn. See #685.
- 🔔 Many small conformance corrections. See #508, #522, #541, #633, #529, #525, #560, #561, #691, #625, #573, #749, #501, #530 and #648.
- 🛡️ Time out TLS handshakes after 5 seconds, in the outstation server and in TLS clients, so a peer that stalls a handshake can't hold up other connections or retries. See #532 and #533.
- 🛡️ Keep TCP servers accepting connections after an accept error, such as running out of file descriptors. See #638.
- 🛡️ Keep UDP masters and outstations running after unexpected or undeliverable datagrams. See #544, #637, #699, #510 and #524.
- 🛡️ Budget the work an outstation spends on a READ or an ASSIGN_CLASS, scaled to the size of its database, so that a request repeating headers that name every point or event is answered with IIN2.2 instead of consuming the CPU. See #855.
- 🛡️ Leave file AUTHENTICATE passwords and auth keys out of decode logging and
Debugoutput. See #520. - ⭐ The outstation processes ASSIGN_CLASS (function code 22), which subset level 3 requires, by default.
OutstationApplication::support_assign_classturns it off, and new callbacks report each accepted request so the application can persist it. See #856. - ⭐ Add master support for
DIRECT_OPERATE_NO_ACK(function code 0x06) in Rust and all bindings. See #466. - ⭐ The bindings'
ReadHandlerreceives analog input deadbands (group 34). See #854. - ⭐ Every public type implements
Debug,dnp3::linkexports its error types, and master task errors gainunsupported_response,unsupported_or_bad_responseandSystemTimeNotAvailable. See #519, #539, #653 and #753. - 🐛 Fix the outstation losing the events of an unsolicited response that was never confirmed. See #546.
- 🐛 Fix an outstation READ including events of a class it didn't ask for. See #634.
- 🐛 Flush TLS writes so the last frame isn't left buffered when the socket is under backpressure. Affects masters and outstations. See #462.
- 🐛 Fix a double free in the bindings when an outstation server fails to bind, for example because the port is already in use. See #469.
- 🐛 Other outstation fixes. See #852, #504, #513, #619, #644, #697 and #545.
- 🐛 Master fixes in file transfer, device attributes, commands, channels shared by several outstations, automatic tasks and keep-alives, and parsing. See #547, #631, #548, #517, #728, #500, #565, #613, #636, #553, #614, #620, #552, #632, #647, #708, #791 and #593.
- 🐛 Link and transport layer fixes. See #586, #550, #658, #635 and #645.
- 🔧 The prebuilt libraries for the C/C++, .NET and Java bindings are about 20% smaller and faster. See #798 and #799.
- 🔧 The prebuilt bindings use AWS-LC for TLS on every platform. The musl and 32-bit ARM Linux libraries switch from ring, which adds post-quantum key exchange and makes them 0.7 to 2.2 MB larger. See #861.
- 📖 Consistent variation descriptions in logging and the bindings' docs, and a guide page on the master's automatic tasks and scheduling. See #781, #787 and #700.
1.7.0
- ⭐ Add outstation
ConnectionManagerfor fine-grained control of TCP and TLS client connections, including dynamic endpoint selection, custom retry logic, and per-connection master address override. See #381, #406. - ⭐ Add
DirectWriteAbsTimetime sync procedure for outstations that don't properly implement IEEE-1815 time sync. See #403. - ⭐ Add optional support for parsing and transmission of zero-length octet strings via global setting. See #379.
- ⭐ Add optional support for AWS libcrypto (aws-lc-rs) as TLS backend. See #378.
- ⭐ Make OctetString constructor public in Java bindings. See #402.
- ⭐ Make HeaderInfo constructor public for mockability in tests. See #404.
- ⭐ Add
Database::discard_unselected_events()to drop undelivered events of selected classes on demand. Opt-in and lossy by design. See #427. - ⭐ Add non-spawning master and outstation task APIs behind the semver-exempt
unstablefeature, for applications that don't want the library callingtokio::spawninternally. See #433. - ⭐ Add
EndpointList::into_connect_handler()andinto_connect_handler_with_options()to build aClientConnectionHandlerfrom an endpoint list. See #433. - 🛡️ Fix inverted
MinTlsVersionmapping, which affects 1.6.0 through 1.7.0-RC3. See #437. - 🔔 Behavior change for existing TLS configurations. Users who set
V13were silently permitting TLS 1.2 and will now reject peers that do not support TLS 1.3. Users on the defaultV12(including all bindings users who never overrode it) will now negotiate TLS 1.3 where the peer supports it, rather than being pinned to TLS 1.2. - 🛡️ Update
rustlsto 0.23.45 to resolve RUSTSEC-2026-0285, in which TLS 1.3 handshake messages were accepted across encryption level boundaries. See #447. - 🛡️ Update
rustls-webpkito 0.103.13 to resolve RUSTSEC-2026-0098 and RUSTSEC-2026-0099, both concerning incorrect acceptance of X.509 name constraints. Exposure is limited toCertificateMode::AuthorityBased. - 🔔 These two dependency updates only affect the prebuilt binary distributions of the bindings (C/C++, .NET, Java). Rust consumers of the
dnp3crate pick up the patched dependencies automatically on rebuild. - 🛡️ Add security policy and automated supply chain scanning. See #394, #440.
- 🔧 Add quality gate to prevent releases when tests fail. See #393.
- 🔧 Automate cargo publish to crates.io in CI release process. See #407.
- 🔧 Better CLI examples with improved organization and documentation. See #375.
- 🔧 Refactor release workflow into separate idempotent jobs for improved reliability.
- 🔔 Rust-only change. The no-spawn TCP outstation server APIs (
Server::add_outstation_no_spawnandServer::bind_no_spawn) no longer attach a tracing span to the futures they return, so non-spawning callers retain full control over instrumentation. Callers that relied on the automaticdnp3-outstation-tcp/tcp-serverspans should wrap the returned future in their own span. See #433. - 📖 Update TLS documentation to clarify empty string behavior for certificate passwords. See #389.
- 🐛 Reset the outstation event buffer on session teardown. Events left mid-delivery when a link died were previously stranded and never re-reported on reconnect, and stale selected events could leak into a later response. See #423.
- 🐛 Avoid an index overflow when iterating ranged octet string data whose final index is
u16::MAX. This only ever tripped the debug-build overflow check after the last item had been yielded; release builds wrapped and produced correct output. See #422.
1.6.0
- ⭐ Add master station support for writing files to the outstation. See #338.
- ⭐ Add master station support for command events (groups 13 and 43). See #332.
- ⭐ Add master station support for group 102. See #335.
- ⭐ Add master and outstation support for UDP. See #353.
- ⭐ Add master station support for acting as a TCP server. See #358.
- ⭐ Add ability to update flags and timestamp without knowing the current value. See #365.
- ⭐ Obtain TCP port from server in Rust API. #331.
1.5.2
- 🐛 Fix bug where the outstation would sleep before all unsolicited data was transmitted. See #341.
1.5.1
- 🔧 Update to oo-bindgen 0.8.6 to improve Java native library loading. See oo-bindgen #124.
- 🔔 This release only affects the Java distribution. It is equivalent to 1.5.0 for other distributions.
1.5.0
- ⭐ Add configuration option that allows outstation to respond to any master. See #316.
- ⭐ Add optional serde support for public config types in Rust. See #303.
- 🔧 Fix cmake download when building C/C++ examples. See #307.
- 📖 Fix FFI docs for g12v1 and remove g12v0 and g41v0. See #308
- 🐛 Fix master task scheduling CPU thrashing under certain conditions. See #312.
- 🐛 Fix bug where
AssociationInformation::task_failwas not properly being called for some tasks. See #313. - 🐛 Update rx509 to 0.2.1 to fix ASN.1 GeneralizedTime parsing. See RASN #2.
1.4.1
- 🐛 Bump rustls to 0.21.1 to resolve #300.
1.4.0
- 🔧 Update to rustls 0.21.0 which allows peer names with IP addresses in the SAN extension.
- 🔧 Move common TLS configuration to its own crate shared with our Modbus library.
- ⭐ PEM parser now supports extracting PKCS#1 private keys, i.e. PEM files with
BEGIN RSA PRIVATE KEY. - ⭐ X.509 name verification may now be disabled in the TLS client and server configurations.
- 📖 Documentation improvements in the bindings via oo-bindgen 0.8.3.
1.3.0
- ⭐ Add master and outstation support for device attributes (group 0).
- ⭐ Add master support for reading files and directories. See #281.
- ⭐ Add ability to specify TCP/TLS client local adapter and connect timeout. See #254.
- ⭐ Add master support for receiving frozen analog inputs (groups 31 and 33). See #256.
- ⭐ Add master and outstation support for analog inputs dead-bands (group 34). See #257.
- ⭐ Add master API for sending freeze requests. Add freeze-at-time to outstation. See #263.
- ⭐ Add a mechanism to the bindings to shut down the Runtime with a timeout. See #271.
- ⭐ Add outstation APIs for tracking the lifetime of events. See #273.
- ⭐ Add enable/disable methods to outstation instances. See #278.
- ⭐ Add TCP/TLS client modes to the outstation API. See #279.
- 🐛 Fix incorrect encoding of octet-string events when adjacent events have different lengths. See #269.
- 🐛 Fix bug where the outstation would respond to a master other than the one configured. See #284.
- 📖 Various FFI documentation improvements. See #250.
1.2.0
- ⭐ Enable TCP_NODELAY by default. See #218.
- ⭐ Enable full link-time optimization (LTO) in release builds. See #223.
- ⭐ Add support for 3 MUSL Linux targets to C/C++ and .NET. See #228.
- ⭐ Use only dependencies from crates.io allowing first release there. See #227.
- ⭐ Internal refactoring to promote code reuse with Rodbus. See: #220, #221, #222.
1.1.0
- ⭐ TCP/TLS server can now filter IPv4 addresses with wildcards. See #208.
- ⭐ Rust crate and FFI/JNI libraries can now be compiled without TLS and/or serial support. See #212.
- ⭐ Add a way to spawn a serial outstation that is tolerant to the port being removed from the OS. See #215.
- ⭐ Produce enhanced third-party license reports for FFI and JNI bindings.
1.0.1
- 🐛 Fix panic when creating serial outstation #203.
- ⭐ Log when OVERFLOW or EVENT classes available IIN bits causes a poll to be scheduled. #25.
- ⭐ Build all Linux FFI/JNI artifacts using rust-cross #197.
- ⭐ Newer rust-cross version produces more portable Linux libraries (older GLIBC).
1.0.0
- First release with stable API