Commit ce2ccc7
authored
Fix transport buffer pooling, limiting, and in-process capture (#3994)
# Description
Fixes transport-buffer pool amplification when
`TransportQuotas.MaxBufferSize` is an exact power of two, adds
injectable buffer-manager policies and a process-wide memory limiter,
and fixes in-process pcap capture of maximum-size UASC chunks.
`BufferManager` previously reserved an ownership cookie after the usable
data in every build. A 65,536-byte limit therefore requested 65,537
bytes from `ArrayPool<byte>.Shared`, selecting the 131,072-byte bucket.
The compatibility `BufferManager` is now a facade over `IBufferManager`;
Release defaults to `FastBufferManager`, Debug defaults to
`CookieBufferManager`, and explicit `TRACK_MEMORY` builds use
`TracingBufferManager`.
`IBufferManagerFactory` and `BufferManagerFactoryOptions` are registered
through dependency injection and wired through raw TCP, HTTPS/WSS, and
Kestrel channel/listener creation while preserving existing direct
constructors. Applications can replace the factory or explicitly select
fast, cookie, or tracing behavior.
`LimitingBufferManager` wraps any implementation and uses a
factory-shared `BufferManagerMemoryLimiter` to cap actual outstanding
bytes across all managers created by that factory. It blocks synchronous
rents without holding manager locks, supports cancellation on transport
I/O paths, accounts for actual pool bucket sizes, rejects impossible or
synchronous re-entrant rents safely, and protects accounting from
failed, foreign, and duplicate returns.
The client and accepted-server TCP transports also retained raw quota
values. The fix carries bucket-safe limits into transport creation and
reconnects, while preserving the active connection’s negotiated receive
limit. Configurable transports receive updated limits during server
reconnect, and every channel independently rejects and faults/reconnects
on chunks above the negotiated limit.
Maximum-size UASC chunks exceeded the synthetic IPv4 total-length field
once TCP/IP headers were added. The capture path now segments those
chunks into sequence-aware synthetic TCP packets sized for both IPv4 and
the pcap snap length. Every capturing transport receives a stable
process-unique synthetic flow identity that is preserved in the full TCP
tuple and independent sequence state. Capture queuing remains
non-blocking and queues or drops complete UASC chunks atomically;
sequence space is reserved before bounded frame admission so dropped
chunks remain visible as TCP gaps, while packetization stays in the
single writer. Key-material snapshots use a separate prioritized
unbounded queue and are drained and disposed reliably during shutdown.
This change includes:
- `IBufferManager`, `IBufferManagerFactory`, factory options, and
compatibility facade;
- fast, cookie, allocation-tracing, and memory-limiting implementations;
- shared DI factory wiring for raw TCP, HTTPS/WSS, and Kestrel
transports;
- Debug/Release/TRACK_MEMORY implementation selection;
- cancellation-aware transport rents and no-loss in-process receive
behavior;
- deterministic ownership, limiter, bucket-size, reconnect,
oversized-chunk, cancellation, and DI tests;
- explicit subscription diagnostics using `ArrayPoolEventSource`;
- pcap framing, sequence-space, atomic-queue, and reassembly regression
tests;
- updated benchmark and dependency-injection documentation.
Measured with 255 and 257 Publish queues plus a slow-consumer scenario,
configured values of both 65,535 and 65,536 used only 65,536-byte
arrays. Every observed rent had a matching return, outstanding buffers
returned to zero, and no Gen 2 collections occurred. The 500-session
baseline also passed for `opc.tcp`, `https`, and `opc.https`, with all
sessions receiving notifications.
## Related Issues
- Fixes #3988
## Checklist
- [x] I have signed the
[CLA](https://opcfoundation.org/license/cla/ContributorLicenseAgreementv1.0.pdf)
and read the
[CONTRIBUTING](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/CONTRIBUTING.md)
doc.
- [x] I have added tests that prove my fix is effective or that my
feature works and increased code coverage.
- [x] I have added all necessary documentation.
- [x] I have verified that my changes do not introduce (new) build or
analyzer warnings.
- [ ] I ran **all** tests locally using the **UA.slnx** solution against
at least .net **framework** and .net **10**, and all passed.
- [ ] I fixed **all** failing and flaky tests in the CI pipelines and
**all** CodeQL warnings.
- [x] I have addressed **all** PR feedback received.1 parent c250db6 commit ce2ccc7
52 files changed
Lines changed: 7883 additions & 468 deletions
File tree
- Docs
- Stack
- Opc.Ua.Bindings.Https
- DependencyInjection
- Https
- Tcp
- Opc.Ua.Core.Diagnostics
- Bindings
- Capture/Sources
- Frame
- Opc.Ua.Core/Stack
- Bindings
- Diagnostics
- Tcp
- Tests
- Opc.Ua.Core.Diagnostics.Tests
- Bindings
- Capture
- Frame
- Opc.Ua.Core.Tests
- Stack
- Diagnostics
- Transport
- Types/Bindings
- Opc.Ua.Sessions.Tests
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
427 | 427 | | |
428 | 428 | | |
429 | 429 | | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
430 | 440 | | |
431 | 441 | | |
432 | 442 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
85 | 85 | | |
86 | 86 | | |
87 | 87 | | |
88 | | - | |
| 88 | + | |
89 | 89 | | |
90 | 90 | | |
91 | 91 | | |
92 | 92 | | |
93 | | - | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
94 | 96 | | |
95 | 97 | | |
96 | 98 | | |
| |||
114 | 116 | | |
115 | 117 | | |
116 | 118 | | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
117 | 148 | | |
118 | 149 | | |
119 | 150 | | |
| |||
Lines changed: 9 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
217 | 217 | | |
218 | 218 | | |
219 | 219 | | |
| 220 | + | |
| 221 | + | |
220 | 222 | | |
221 | 223 | | |
222 | | - | |
223 | | - | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
224 | 228 | | |
225 | 229 | | |
226 | 230 | | |
| |||
229 | 233 | | |
230 | 234 | | |
231 | 235 | | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
232 | 239 | | |
233 | 240 | | |
234 | 241 | | |
| |||
Lines changed: 8 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
63 | 63 | | |
64 | 64 | | |
65 | 65 | | |
66 | | - | |
67 | | - | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
68 | 74 | | |
69 | 75 | | |
70 | 76 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
59 | 59 | | |
60 | 60 | | |
61 | 61 | | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
62 | 68 | | |
63 | 69 | | |
64 | 70 | | |
| |||
Lines changed: 55 additions & 13 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
76 | 76 | | |
77 | 77 | | |
78 | 78 | | |
79 | | - | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
80 | 84 | | |
81 | 85 | | |
82 | 86 | | |
| |||
103 | 107 | | |
104 | 108 | | |
105 | 109 | | |
106 | | - | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
107 | 115 | | |
108 | 116 | | |
109 | 117 | | |
| |||
129 | 137 | | |
130 | 138 | | |
131 | 139 | | |
132 | | - | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
133 | 145 | | |
134 | 146 | | |
135 | 147 | | |
| |||
155 | 167 | | |
156 | 168 | | |
157 | 169 | | |
158 | | - | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
159 | 175 | | |
160 | 176 | | |
161 | 177 | | |
| |||
321 | 337 | | |
322 | 338 | | |
323 | 339 | | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
324 | 345 | | |
325 | | - | |
326 | | - | |
327 | | - | |
328 | 346 | | |
329 | 347 | | |
330 | 348 | | |
| |||
338 | 356 | | |
339 | 357 | | |
340 | 358 | | |
341 | | - | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
342 | 364 | | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
343 | 379 | | |
| 380 | + | |
| 381 | + | |
344 | 382 | | |
345 | 383 | | |
346 | 384 | | |
| |||
550 | 588 | | |
551 | 589 | | |
552 | 590 | | |
553 | | - | |
554 | | - | |
555 | | - | |
| 591 | + | |
| 592 | + | |
| 593 | + | |
| 594 | + | |
556 | 595 | | |
557 | 596 | | |
558 | 597 | | |
| |||
1786 | 1825 | | |
1787 | 1826 | | |
1788 | 1827 | | |
1789 | | - | |
| 1828 | + | |
| 1829 | + | |
1790 | 1830 | | |
1791 | 1831 | | |
1792 | 1832 | | |
| |||
1998 | 2038 | | |
1999 | 2039 | | |
2000 | 2040 | | |
2001 | | - | |
| 2041 | + | |
| 2042 | + | |
2002 | 2043 | | |
2003 | 2044 | | |
2004 | 2045 | | |
| |||
2405 | 2446 | | |
2406 | 2447 | | |
2407 | 2448 | | |
| 2449 | + | |
2408 | 2450 | | |
2409 | 2451 | | |
2410 | 2452 | | |
| |||
Lines changed: 8 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
120 | 120 | | |
121 | 121 | | |
122 | 122 | | |
123 | | - | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
124 | 127 | | |
125 | 128 | | |
126 | 129 | | |
| |||
167 | 170 | | |
168 | 171 | | |
169 | 172 | | |
170 | | - | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
171 | 177 | | |
172 | 178 | | |
173 | 179 | | |
| |||
0 commit comments