Skip to content

Feature | Add scaffolding for SSRP response parsing#3741

Open
edwardneal wants to merge 9 commits into
dotnet:mainfrom
edwardneal:feat/ssrp/01-scaffolding
Open

Feature | Add scaffolding for SSRP response parsing#3741
edwardneal wants to merge 9 commits into
dotnet:mainfrom
edwardneal:feat/ssrp/01-scaffolding

Conversation

@edwardneal
Copy link
Copy Markdown
Contributor

Description

This is the first of four or five PRs which introduce an SSRP client to the managed SNI. This PR doesn't actually introduce any parsing code - it just adds test cases and lays some scaffolding/infrastructure down for the next one.

Key points of interest here:

  • Around two thirds of the additions here are test cases. I've tried to cover as many of these as I can see based upon the MC-SQLR specification, with a particular focus on malformed data. These will end up parsing unsanitised network traffic, so I'm completely open to adding any others which would cover malicious traffic.
  • I'm planning to make fairly heavy use of ReadOnlySequence<byte> to store packet buffers, then read the SSRP responses from them. This introduces the use of PacketBuffer and ReadOnlySequenceUtilities.
  • The existence of ReadOnlySequenceUtilities is a workaround; netcore has a SequenceReader<T> type in-box. This isn't available to netfx though, and I didn't think it was worth maintaining two sets of fairly simple logic. We could alternatively bring the SequenceReader<T> and SequenceReaderExtensions source code in-tree, as a few other libraries have done (examples 1 and 2.)

Issues

Contributes to #3700.

Testing

There's nothing to test in this PR, so CI should validate it.

@apoorvdeshmukh
Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 2 pipeline(s).

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces test infrastructure and placeholder unit tests for SSRP (SQL Server Resolution Protocol) packet processing functionality. The changes lay the groundwork for testing both SQL Data Source responses and DAC (Dedicated Admin Connection) responses.

  • Adds comprehensive test data generation utilities for creating and validating SSRP packet structures
  • Implements utility classes for working with ReadOnlySequence<byte> to parse binary network packets
  • Creates placeholder test methods marked with ActiveIssue that reference a planned implementation (issue #3700)

Reviewed Changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
SsrpPacketTestData.cs Provides test data generators for various valid and invalid SSRP packet scenarios, including SVR_RESP messages, DAC responses, and edge cases
SqlDataSourceResponseProcessorTest.cs Placeholder unit tests for SQL Data Source response processing, covering empty buffers, invalid responses, and valid response data
DacResponseProcessorTest.cs Placeholder unit tests for DAC response processing with similar coverage patterns
CodeAnalysis.cs Adds NotNullWhenAttribute for better null-state analysis in conditional scenarios
ReadOnlySequenceUtilities.cs Extension methods for reading bytes and little-endian ushort values from ReadOnlySequence<byte>
PacketBuffer.cs Linked list node implementation for building ReadOnlySequence<byte> from multiple buffers
netfx/.../Microsoft.Data.SqlClient.csproj Includes new common source files in .NET Framework project
netcore/.../Microsoft.Data.SqlClient.csproj Includes new common source files in .NET Core project

Comment on lines +21 to +23
public static bool ReadByte(this ref ReadOnlySequence<byte> sequence, ref ReadOnlySpan<byte> currSpan, ref long currPos, out byte value)
{
if (sequence.Length < sizeof(byte))
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The currPos parameter is incremented but its updated value may not reflect the actual state if the sequence is too short (line 23-27). Consider moving the increment after the length check succeeds, or document that callers should not rely on currPos when the method returns false.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

currPos is the current position in the ReadOnlySequence<byte>. If there's not enough space in the sequence, the method doesn't advance and it's thus appropriate to leave currPos untouched.

Comment on lines +61 to +63
public static bool ReadLittleEndian(this ref ReadOnlySequence<byte> sequence, ref ReadOnlySpan<byte> currSpan, ref long currPos, out ushort value)
{
if (sequence.Length < sizeof(ushort))
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the ReadByte method, the currPos parameter is incremented (line 69) before the actual read operation, which could leave it in an inconsistent state if the sequence length check fails. Consider moving the increment after successful validation or documenting this behavior.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

@edwardneal edwardneal Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per the ReadByte method - currPos is always in a consistent state. Once execution reaches line 69, there's guaranteed to be enough space in the ReadOnlySpan<byte> - the only question is whether we can directly read it from the current span, or need to reassemble it because byte 1 is in the current span and byte 2 is in the next span.

@paulmedynski paulmedynski self-assigned this Nov 4, 2025
@cheenamalhotra cheenamalhotra moved this from To triage to In review in SqlClient Board Nov 17, 2025
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Dec 5, 2025

This pull request has been marked as stale due to inactivity for more than 30 days.

If you would like to keep this pull request open, please provide an update or respond to any comments. Otherwise, it will be closed automatically in 7 days.

@github-actions github-actions Bot added the Stale The Issue or PR has become stale and will be automatically closed shortly if no activity occurs. label Dec 5, 2025
@edwardneal
Copy link
Copy Markdown
Contributor Author

This PR is not stale.

@paulmedynski paulmedynski moved this from In review to Backlog in SqlClient Board Dec 5, 2025
@paulmedynski
Copy link
Copy Markdown
Contributor

@edwardneal Can you rebase to main (no merge commit) to pickup the latest pipeline and CodeQL configs? That should eliminate the unnecessary CI checks and unblock the Code scanning.

@paulmedynski
Copy link
Copy Markdown
Contributor

Since this is a new feature, we will need to prioritize our review of it against existing priorities, so this may not see much attention until early 2026. @edwardneal Do you think you could have all of the work for SSRP ready for the 7.0 GA in March?

@paulmedynski paulmedynski added Approval Needed Issues/PRs that require approval from the maintainers before changes will be accepted. and removed Stale The Issue or PR has become stale and will be automatically closed shortly if no activity occurs. labels Dec 5, 2025
This consists of:
* ReadOnlySequenceSegment derivative,
* Utilities to read data from a ReadOnlySequence<byte>
* Test cases
@edwardneal edwardneal force-pushed the feat/ssrp/01-scaffolding branch from 3e5d56f to c8f6688 Compare December 5, 2025 19:33
@paulmedynski
Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 2 pipeline(s).

@edwardneal
Copy link
Copy Markdown
Contributor Author

Thanks @paulmedynski. I tried rebasing, but that went badly wrong and the CodeQL error persisted. I think I've fixed it now, and the build looks like it's triggered properly.

March is enough time to implement the feature, and I have a local branch with the SSRP response parsing logic and test cases. I definitely wouldn't prioritise SqlDataSourceEnumerator above the other changes in 7.0 though, and I think it's likely to be a little more sensitive to review (since the only way it can work is by parsing untrusted network broadcasts.)

I'm happy enough for this series of PRs to lie dormant until post-GA. Implementation doesn't introduce a breaking change, it just means that clients can enumerate SQL Server instances on the local LAN rather than having GetDataSources throw an exception.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jan 5, 2026

This pull request has been marked as stale due to inactivity for more than 30 days.

If you would like to keep this pull request open, please provide an update or respond to any comments. Otherwise, it will be closed automatically in 7 days.

@github-actions github-actions Bot added the Stale The Issue or PR has become stale and will be automatically closed shortly if no activity occurs. label Jan 5, 2026
@edwardneal
Copy link
Copy Markdown
Contributor Author

This PR is not stale.

@paulmedynski paulmedynski removed the Stale The Issue or PR has become stale and will be automatically closed shortly if no activity occurs. label Jan 5, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Feb 5, 2026

This pull request has been marked as stale due to inactivity for more than 30 days.

If you would like to keep this pull request open, please provide an update or respond to any comments. Otherwise, it will be closed automatically in 7 days.

@github-actions github-actions Bot added the Stale The Issue or PR has become stale and will be automatically closed shortly if no activity occurs. label Feb 5, 2026
@edwardneal
Copy link
Copy Markdown
Contributor Author

This PR is not stale.

@github-actions github-actions Bot removed the Stale The Issue or PR has become stale and will be automatically closed shortly if no activity occurs. label Feb 6, 2026
@paulmedynski
Copy link
Copy Markdown
Contributor

@edwardneal - New conflicts here. I will work to get this approved, reviewed, and merged ASAP to avoid wasting your time with further conflicts.

@edwardneal
Copy link
Copy Markdown
Contributor Author

Thanks @paulmedynski, I've just merged.

Most of the conflicts have come from PRs which predate the project merge. I'm not expecting many conflicts in this area of the codebase moving forwards, so we don't need to rush and displace any other priorities on that basis.

@apoorvdeshmukh
Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 2 pipeline(s).

Copy link
Copy Markdown
Contributor

@benrr101 benrr101 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not entirely sure how this all comes together, buuuuuut I think it's fine. Requesting a handful of style changes for the tests, and a couple things to double check before approving.

@github-project-automation github-project-automation Bot moved this from Backlog to In progress in SqlClient Board May 12, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented May 12, 2026

Codecov Report

❌ Patch coverage is 0% with 54 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.38%. Comparing base (be95ca2) to head (9c48a65).
⚠️ Report is 11 commits behind head on main.

Files with missing lines Patch % Lines
...Microsoft/Data/Common/ReadOnlySequenceUtilities.cs 0.00% 40 Missing ⚠️
...qlClient/src/Microsoft/Data/Common/PacketBuffer.cs 0.00% 12 Missing ⚠️
...lient/src/System/Diagnostics/CodeAnalysis.netfx.cs 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3741      +/-   ##
==========================================
- Coverage   65.96%   64.38%   -1.59%     
==========================================
  Files         275      273       -2     
  Lines       42993    65831   +22838     
==========================================
+ Hits        28361    42383   +14022     
- Misses      14632    23448    +8816     
Flag Coverage Δ
CI-SqlClient ?
PR-SqlClient-Project 64.38% <0.00%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@apoorvdeshmukh apoorvdeshmukh added Author attention needed PRs that require author to respond or make updates to PR. and removed Approval Needed Issues/PRs that require approval from the maintainers before changes will be accepted. labels May 13, 2026
@edwardneal
Copy link
Copy Markdown
Contributor Author

Thanks @benrr101. There are a lot of formatting changes, but I think I've covered everything except for the names of the utility methods.

The tests are empty because they're covering components which don't exist yet. As they're added, I'll populate them and set them to run in CI. They're in this PR so that we can confirm whether I need to add any other test cases to the set. I'm aware these components will eventually need to be able to parse real-world LAN traffic, so it needs to be tested against malicious packets.

@apoorvdeshmukh
Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 2 pipeline(s).

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Comment on lines +374 to +375
validTcpInfo,
omitVersion: true))),
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes - fixed.

Comment on lines +428 to +440
CreateSVR_RESPMessage("tcp"),

// Port is non-numeric
CreateSVR_RESPMessage("tcp;one"),

// Port is > ushort.MaxValue
CreateSVR_RESPMessage("tcp;65536"),

// Port is < 0
CreateSVR_RESPMessage("tcp;-1")
];

static ReadOnlySequence<byte> CreateSVR_RESPMessage(string tcpInfo) =>
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SCREAMING_SNAKE_CASE has now been removed.

Correct screaming snake case method.
Correct ensure that test case provides a zero-length Version field (not an absent one.)
Copy link
Copy Markdown
Contributor

@benrr101 benrr101 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the changes! Looks good to me!

@benrr101
Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 2 pipeline(s).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Author attention needed PRs that require author to respond or make updates to PR.

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

6 participants