Skip to content

Fix v3 context name#690

Open
benoit-bernard wants to merge 3 commits intolextudio:masterfrom
benoit-bernard:fix-v3-contextName
Open

Fix v3 context name#690
benoit-bernard wants to merge 3 commits intolextudio:masterfrom
benoit-bernard:fix-v3-contextName

Conversation

@benoit-bernard
Copy link
Copy Markdown

In V3, to connect to some devices, we need to initialize the scope contextName from the discovery

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Jan 3, 2025

CLA assistant check
All committers have signed the CLA.

Copy link
Copy Markdown
Collaborator

@lextm lextm left a comment

Choose a reason for hiding this comment

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

Default values should be OctetString.Empty instead of null. And then you can annotate the parameters as non-nullable.

@benoit-bernard benoit-bernard requested a review from lextm January 10, 2025 07:22
@benoit-bernard
Copy link
Copy Markdown
Author

Hello @lextm,

Do you need another fix / commit ?

Thanks

Copy link
Copy Markdown

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 adds support for specifying an SNMPv3 contextName during discovery so that discovery requests can target devices that require a non-empty context name.

Changes:

  • Added Discover/DiscoverAsync overloads (net471 + net6) that accept a contextName and pass it into v3 discovery messages.
  • Added Messenger.GetNextDiscovery overload that accepts contextName.
  • Added new Discovery constructors that populate Scope.ContextName and updated v3 discovery creation to use them.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 7 comments.

File Description
SharpSnmpLib/Messaging/Net6Discoverer.cs Adds overloads to pass contextName into v3 discovery for .NET 6+ discoverer.
SharpSnmpLib/Messaging/Discoverer.cs Adds overloads to pass contextName into v3 discovery for non-.NET6 discoverer.
SharpSnmpLib/Messaging/Messenger.cs Adds GetNextDiscovery overload that accepts contextName (and changes default to call it).
SharpSnmpLib/Messaging/Discovery.cs Adds constructors supporting contextName and modifies response handling logic in GetResponse.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +72 to 76
/// <param name="interval">The discovering time interval, in milliseconds.</param>
/// <param name="contextName">The optional Context Name.</param>
/// <remarks><paramref name="broadcastAddress"/> must be configured to a valid multicast address when IPv6 is used. For example, "[ff02::1]:161"</remarks>
public void Discover(VersionCode version, IPEndPoint broadcastAddress, OctetString community, int interval, OctetString contextName)
{
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

The new Discover overload takes contextName as a required non-nullable argument, but the XML docs call it optional and it’s only meaningful for v3. Consider making it nullable/optional (and defaulting null to OctetString.Empty) to avoid surprising ArgumentNullExceptions for callers who treat it as optional.

Copilot uses AI. Check for mistakes.
Comment on lines +52 to 57
/// <param name="community">The community.</param>
/// <param name="token">The cancellation token.</param>
/// <param name="contextName">The optional context name.</param>
/// <remarks><paramref name="broadcastAddress"/> must be an IPv4 address. IPv6 is not yet supported here.</remarks>
public void Discover(VersionCode version, IPEndPoint broadcastAddress, OctetString? community, CancellationToken token, OctetString contextName)
{
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

The new Discover/DiscoverAsync overloads take contextName as a required non-nullable argument, but docs describe it as optional. Consider making contextName nullable/optional (and defaulting null to OctetString.Empty) so callers don’t get unexpected ArgumentNullExceptions when Scope is constructed.

Copilot uses AI. Check for mistakes.
Comment on lines +84 to +98
public Discovery(int messageId, int requestId, int maxMessageSize, OctetString contextName)
{
_discovery = new GetRequestMessage(
VersionCode.V3,
new Header(
new Integer32(messageId),
new Integer32(maxMessageSize),
Levels.Reportable),
DefaultSecurityParameters,
new Scope(
OctetString.Empty,
contextName,
new GetRequestPdu(requestId, new List<Variable>())),
DefaultPrivacyProvider.DefaultPair,
null);
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

New contextName support in Discovery constructors isn’t covered by unit tests. Since there are existing messaging/parse tests, consider adding a test that builds a Discovery with a non-empty contextName and asserts the serialized bytes (or parsed Scope.ContextName) contains that contextName.

Copilot uses AI. Check for mistakes.
/// Returns a new discovery request.
/// </summary>
/// <param name="type">Message type.</param>
/// <param name="contextName">The optional context name.</param>
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

XML doc for GetNextDiscovery(SnmpType type) includes a tag, but the method has no such parameter. This will produce incorrect generated docs/warnings; remove that param tag (keep it only on the overload that actually accepts contextName).

Suggested change
/// <param name="contextName">The optional context name.</param>

Copilot uses AI. Check for mistakes.
Comment on lines +77 to +85
/// <summary>
/// Initializes a new instance of the <see cref="Discovery"/> class.
/// </summary>
/// <param name="requestId">The request id.</param>
/// <param name="messageId">The message id.</param>
/// <param name="maxMessageSize">The max size of message.</param>
/// <param name="contextName">The optional Context Name.</param>
public Discovery(int messageId, int requestId, int maxMessageSize, OctetString contextName)
{
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

The new Discovery(.., OctetString contextName) constructor documents parameters as requestId then messageId, but the signature is (messageId, requestId, ...). Please fix the XML doc param names/order so they match the actual arguments.

Copilot uses AI. Check for mistakes.
Comment on lines +331 to +341
var response = _discovery.GetResponse(timeout, receiver, Empty, socket);

try
{
return (ReportMessage)response;
}
catch
{
//The cast was not possible with a system that needed contextname=public
return new ReportMessage(response.Version, response.Header, response.Parameters, response.Scope, response.Privacy, response?.ToBytes());
}
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

In the fallback path, ReportMessage is constructed with response.ToBytes() passed as the length argument. That parameter represents ASN.1 length bytes (see StreamExtension.AppendBytes: it writes the provided length directly), so passing the full message bytes will produce an invalid encoding. If you need to handle non-Report responses, avoid reusing ToBytes() as the length; instead compute a new message (pass null for length) and gate this path using a type check (e.g., response is ReportMessage).

Copilot uses AI. Check for mistakes.
Comment on lines +83 to +98
/// <param name="contextName">The optional Context Name.</param>
public Discovery(int messageId, int requestId, int maxMessageSize, OctetString contextName)
{
_discovery = new GetRequestMessage(
VersionCode.V3,
new Header(
new Integer32(messageId),
new Integer32(maxMessageSize),
Levels.Reportable),
DefaultSecurityParameters,
new Scope(
OctetString.Empty,
contextName,
new GetRequestPdu(requestId, new List<Variable>())),
DefaultPrivacyProvider.DefaultPair,
null);
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

contextName is described as optional but the parameter is non-nullable and is passed directly into Scope, which throws if contextName is null. Consider accepting OctetString? (or validating and defaulting null to OctetString.Empty) so callers don’t hit an unexpected ArgumentNullException inside Scope.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants