ClientBuilder

Struct ClientBuilder 

Source
pub struct ClientBuilder { /* private fields */ }
Expand description

Builder for constructing SNMP clients.

This is the single entry point for client construction. It supports all SNMP versions (v1, v2c, v3) through the Auth enum.

§Example

use async_snmp::{Auth, ClientBuilder, Retry};
use std::time::Duration;

// Simple v2c client
let client = ClientBuilder::new("192.168.1.1:161", Auth::v2c("public"))
    .connect().await?;

// v3 client with authentication
let client = ClientBuilder::new("192.168.1.1:161",
    Auth::usm("admin").auth(async_snmp::AuthProtocol::Sha256, "password"))
    .timeout(Duration::from_secs(10))
    .retry(Retry::fixed(5, Duration::ZERO))
    .connect().await?;

Implementations§

Source§

impl ClientBuilder

Source

pub fn new(target: impl Into<String>, auth: impl Into<Auth>) -> Self

Create a new client builder.

§Arguments
  • target - The target address (e.g., “192.168.1.1:161”)
  • auth - Authentication configuration (community or USM)
§Example
use async_snmp::{Auth, ClientBuilder};

// Using Auth::default() for v2c with "public" community
let builder = ClientBuilder::new("192.168.1.1:161", Auth::default());

// Using Auth::v1() for SNMPv1
let builder = ClientBuilder::new("192.168.1.1:161", Auth::v1("private"));

// Using Auth::usm() for SNMPv3
let builder = ClientBuilder::new("192.168.1.1:161",
    Auth::usm("admin").auth(async_snmp::AuthProtocol::Sha256, "password"));
Source

pub fn timeout(self, timeout: Duration) -> Self

Set the request timeout (default: 5 seconds).

This is the time to wait for a response before retrying or failing. The total time for a request may be timeout * (retries + 1).

§Example
use async_snmp::{Auth, ClientBuilder};
use std::time::Duration;

let builder = ClientBuilder::new("192.168.1.1:161", Auth::v2c("public"))
    .timeout(Duration::from_secs(10));
Source

pub fn retry(self, retry: impl Into<Retry>) -> Self

Set the retry configuration (default: 3 retries, no backoff).

On timeout, the client resends the request up to this many times before returning an error. Retries are disabled for TCP (which handles reliability at the transport layer).

§Example
use async_snmp::{Auth, ClientBuilder, Retry};
use std::time::Duration;

// No retries
let builder = ClientBuilder::new("192.168.1.1:161", Auth::v2c("public"))
    .retry(Retry::none());

// 5 retries with no delay (immediate retry on timeout)
let builder = ClientBuilder::new("192.168.1.1:161", Auth::v2c("public"))
    .retry(Retry::fixed(5, Duration::ZERO));

// Fixed delay between retries
let builder = ClientBuilder::new("192.168.1.1:161", Auth::v2c("public"))
    .retry(Retry::fixed(3, Duration::from_millis(200)));

// Exponential backoff with jitter
let builder = ClientBuilder::new("192.168.1.1:161", Auth::v2c("public"))
    .retry(Retry::exponential(5)
        .max_delay(Duration::from_secs(5))
        .jitter(0.25));
Source

pub fn max_oids_per_request(self, max: usize) -> Self

Set the maximum OIDs per request (default: 10).

Requests with more OIDs than this limit are automatically split into multiple batches. Some devices have lower limits on the number of OIDs they can handle in a single request.

§Example
use async_snmp::{Auth, ClientBuilder};

// For devices with limited request handling capacity
let builder = ClientBuilder::new("192.168.1.1:161", Auth::v2c("public"))
    .max_oids_per_request(5);

// For high-capacity devices, increase to reduce round-trips
let builder = ClientBuilder::new("192.168.1.1:161", Auth::v2c("public"))
    .max_oids_per_request(50);
Source

pub fn max_repetitions(self, max: u32) -> Self

Set max-repetitions for GETBULK operations (default: 25).

Controls how many values are requested per GETBULK PDU during walks. This is a performance tuning parameter with trade-offs:

  • Higher values: Fewer network round-trips, faster walks on reliable networks. But larger responses risk UDP fragmentation or may exceed agent response buffer limits (causing truncation).
  • Lower values: More round-trips (higher latency), but smaller responses that fit within MTU limits.

The default of 25 is conservative. For local/reliable networks with capable agents, values of 50-100 can significantly speed up large walks.

§Example
use async_snmp::{Auth, ClientBuilder};

// Lower value for agents with small response buffers or lossy networks
let builder = ClientBuilder::new("192.168.1.1:161", Auth::v2c("public"))
    .max_repetitions(10);

// Higher value for fast local network walks
let builder = ClientBuilder::new("192.168.1.1:161", Auth::v2c("public"))
    .max_repetitions(50);
Source

pub fn walk_mode(self, mode: WalkMode) -> Self

Override walk behavior for devices with buggy GETBULK (default: Auto).

  • WalkMode::Auto: Use GETNEXT for v1, GETBULK for v2c/v3
  • WalkMode::GetNext: Always use GETNEXT (slower but more compatible)
  • WalkMode::GetBulk: Always use GETBULK (faster, errors on v1)
§Example
use async_snmp::{Auth, ClientBuilder, WalkMode};

// Force GETNEXT for devices with broken GETBULK implementation
let builder = ClientBuilder::new("192.168.1.1:161", Auth::v2c("public"))
    .walk_mode(WalkMode::GetNext);

// Force GETBULK for faster walks (only v2c/v3)
let builder = ClientBuilder::new("192.168.1.1:161", Auth::v2c("public"))
    .walk_mode(WalkMode::GetBulk);
Source

pub fn oid_ordering(self, ordering: OidOrdering) -> Self

Set OID ordering behavior for walk operations (default: Strict).

  • OidOrdering::Strict: Require strictly increasing OIDs. Most efficient.
  • OidOrdering::AllowNonIncreasing: Allow non-increasing OIDs with cycle detection. Uses O(n) memory to track seen OIDs.

Use AllowNonIncreasing for buggy agents that return OIDs out of order.

Warning: AllowNonIncreasing uses O(n) memory. Always pair with max_walk_results to bound memory usage.

§Example
use async_snmp::{Auth, ClientBuilder, OidOrdering};

// Use relaxed ordering with a safety limit
let builder = ClientBuilder::new("192.168.1.1:161", Auth::v2c("public"))
    .oid_ordering(OidOrdering::AllowNonIncreasing)
    .max_walk_results(10_000);
Source

pub fn max_walk_results(self, limit: usize) -> Self

Set maximum results from a single walk operation (default: unlimited).

Safety limit to prevent runaway walks. Walk terminates normally when limit is reached.

§Example
use async_snmp::{Auth, ClientBuilder};

// Limit walks to at most 10,000 results
let builder = ClientBuilder::new("192.168.1.1:161", Auth::v2c("public"))
    .max_walk_results(10_000);
Source

pub fn engine_cache(self, cache: Arc<EngineCache>) -> Self

Set shared engine cache (V3 only, for high-throughput polling).

Allows multiple clients to share discovered engine state, reducing the number of discovery requests. This is particularly useful when polling many devices with SNMPv3.

§Example
use async_snmp::{Auth, AuthProtocol, ClientBuilder, EngineCache};
use std::sync::Arc;

// Create a shared engine cache
let cache = Arc::new(EngineCache::new());

// Multiple clients can share the same cache
let builder1 = ClientBuilder::new("192.168.1.1:161",
    Auth::usm("admin").auth(AuthProtocol::Sha256, "password"))
    .engine_cache(cache.clone());

let builder2 = ClientBuilder::new("192.168.1.2:161",
    Auth::usm("admin").auth(AuthProtocol::Sha256, "password"))
    .engine_cache(cache.clone());
Source

pub fn context_engine_id(self, engine_id: impl Into<Vec<u8>>) -> Self

Override the context engine ID (V3 only).

By default, the context engine ID is the same as the authoritative engine ID discovered during engine discovery. Use this to override for:

  • Proxy scenarios where requests route through an intermediate agent
  • Devices that require a specific context engine ID
  • Pre-configured engine IDs from device documentation

The engine ID should be provided as raw bytes (not hex-encoded).

Source

pub async fn connect(self) -> Result<Client<UdpHandle>, Error>

Connect via UDP (default).

Creates a new UDP socket and connects to the target address. This is the recommended connection method for most use cases due to UDP’s lower overhead compared to TCP.

For high-throughput scenarios with many targets, consider using UdpTransport with build_with().

§Errors

Returns an error if the configuration is invalid or the connection fails.

§Example
use async_snmp::{Auth, ClientBuilder};

let client = ClientBuilder::new("192.168.1.1:161", Auth::v2c("public"))
    .connect()
    .await?;
Source

pub fn build_with( self, transport: &UdpTransport, ) -> Result<Client<UdpHandle>, Error>

Build a client using a shared UDP transport.

Creates a handle for the builder’s target address from the given transport. This is the recommended way to create multiple clients that share a socket.

§Example
use async_snmp::{Auth, ClientBuilder};
use async_snmp::transport::UdpTransport;

let transport = UdpTransport::bind("0.0.0.0:0").await?;

let client1 = ClientBuilder::new("192.168.1.1:161", Auth::v2c("public"))
    .build_with(&transport)?;
let client2 = ClientBuilder::new("192.168.1.2:161", Auth::v2c("public"))
    .build_with(&transport)?;
Source

pub async fn connect_tcp(self) -> Result<Client<TcpTransport>, Error>

Connect via TCP.

Establishes a TCP connection to the target. Use this when:

  • UDP is blocked by firewalls
  • Messages exceed UDP’s maximum datagram size
  • Reliable delivery is required

Note that TCP has higher overhead than UDP due to connection setup and per-message framing.

§Errors

Returns an error if the configuration is invalid or the connection fails.

§Example
use async_snmp::{Auth, ClientBuilder};

let client = ClientBuilder::new("192.168.1.1:161", Auth::v2c("public"))
    .connect_tcp()
    .await?;
Source

pub fn build<T: Transport>(self, transport: T) -> Result<Client<T>, Error>

Build a client with a custom transport.

Use this method when you need:

  • A custom transport implementation
  • To reuse an existing transport

For UDP shared transport usage, prefer build_with().

§Errors

Returns an error if the configuration is invalid.

§Example
use async_snmp::{Auth, ClientBuilder};
use async_snmp::transport::UdpTransport;

// Create a transport
let transport = UdpTransport::bind("0.0.0.0:0").await?;

// Create a handle for a specific target
let handle = transport.handle("192.168.1.1:161".parse().unwrap());

// Build client with the handle
let client = ClientBuilder::new("192.168.1.1:161", Auth::v2c("public"))
    .build(handle)?;

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more