2 Commits

Author SHA1 Message Date
Marc Schier c781514ad5 Refactor pcap diagnostics: decorator binding + rename to Opc.Ua.Bindings.Pcap
Three changes addressing the design feedback on PR #3855:

1. Renamed Stack/Opc.Ua.Diagnostics.Pcap -> Stack/Opc.Ua.Bindings.Pcap (and the corresponding test project). PackageId, AssemblyName and RootNamespace updated to Opc.Ua.Bindings.Pcap; references in McpServer, signlists, slnx files, docs, and the interop-tester agent updated; Opc.Ua.Core's InternalsVisibleTo entries updated.

2. Replaced UaSCUaBinaryChannel.FrameCaptureSink + per-call NotifyFrameCaptureSink null check with a transport-binding decorator. New files in Opc.Ua.Bindings.Pcap/Bindings:
   - IChannelCaptureRegistry / ChannelCaptureRegistry: singleton with a volatile IFrameCaptureSink slot (1 atomic write to switch recording on/off).
   - CapturingMessageSocket / CapturingMessageSocketFactory: IMessageSocket decorator that taps Send/Receive bytes via a single volatile read of CurrentObserver.
   - PcapTransportChannelBinding: ITransportChannelFactory decorator that injects the capturing socket factory into every TcpTransportChannel and wires ISecureChannel.OnTokenActivated through to the active observer.
   - PcapBindings.Install(): non-DI installer for direct TransportBindings.Channels.SetBinding wiring.

   IFrameCaptureSink moved to Opc.Ua.Core/Stack/Bindings and gained an OnTokenActivated method so the binding can publish key material alongside chunks. UaSCUaBinaryChannel.FrameCaptureSink property and all three NotifyFrameCaptureSink call sites removed - hot path returns to original shape with zero indirection when the binding is not installed. IMessageSocketAsyncEventArgs gains Offset + Count getters (additive).

   AddOpcUaDiagnosticsPcap/Formatters/Replay extension methods renamed to AddOpcUaBindingsPcap[Formatters|Replay]; the new AddOpcUaBindingsPcap also installs the binding into TransportBindings.Channels.

   InProcessClientCaptureSource / InProcessServerCaptureSource: dropped reflection-based AttachClientChannel/AttachServerChannel. The source itself implements IFrameCaptureSink and on Start publishes itself as the registry observer; on Stop clears it. McpServer's PacketCaptureTools simplified accordingly (no more per-channel attach loop).

3. Discarded the source-generator suggestion. Confirmed that the dissection path already 100% reuses the source-generated decoders: UaSCUaBinaryChannel.ReadSymmetricMessage for chunk decryption and BinaryDecoder.ReadEncodeable + EncodeableFactory.GlobalFactory (populated by Tools/Opc.Ua.SourceGeneration's DataTypeGenerator) for service-type decoding. Emitting additional dissection code would duplicate what's already there.

Validation:
- Full UA.slnx builds clean: 0 errors, 2 pre-existing unrelated warnings.
- All 53 tests pass on net10.0 (49 existing + 4 new CapturingMessageSocketTests covering hot-path: not-installed/installed-off/installed-on costs, byte equality, exception isolation).
- CI command line (dotnet build/test --framework net10.0 --configuration Release /p:CustomTestTarget=net10.0) reproduces clean locally.
2026-06-07 21:53:53 +02:00
Marc Schier cbd84388d9 Add OPC UA packet capture, offline decoding and replay (Opc.Ua.Diagnostics.Pcap)
Adds a new diagnostics library (Stack/Opc.Ua.Diagnostics.Pcap) plus 13 MCP tools that capture OPC UA traffic, decode it offline by reusing the stack's own UaSCUaBinaryChannel, and replay it. Includes additive stack hooks (IFrameCaptureSink, TcpListenerChannel.OnTokenActivated), four capture sources (nic / inproc-client / inproc-server / replay), two keylog formats (.uakeys.json, .uakeys.txt), six output formats (pcap, pcapng, json, csv, text, service-timeline), and mock-server / mock-client replay engines. 49 new tests pass; no regressions in the 163 existing transport tests; full UA.slnx builds clean.
2026-06-06 16:31:41 +02:00