Skip to content

Conversation

@edwardneal
Copy link
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.

@edwardneal edwardneal requested a review from a team as a code owner November 1, 2025 21:02
@apoorvdeshmukh
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 2 pipeline(s).

Copy link
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 +24 to +25
/// <see cref="DacResponseProcessorTest.Process_EmptyBuffer_ReturnsFalse"/>
/// <see cref="SqlDataSourceResponseProcessorTest.Process_EmptyBuffer_ReturnsFalse"/>
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 <see cref> tags reference test methods, but the standard pattern is to reference types or members that are part of the code contract, not test methods. Consider using plain text or comments instead of <see cref> for test method references, as these create documentation dependencies that can break if test method names change.

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

Choose a reason for hiding this comment

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

I'd personally describe the test method and the test's input to be part of the same overall test contract. <see cref> is appropriate here.

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
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
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
@github-actions
Copy link

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
Contributor Author

This PR is not stale.

@paulmedynski
Copy link
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
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
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@edwardneal
Copy link
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.

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

Labels

Approval Needed Issues/PRs that require approval from the maintainers before changes will be accepted.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants