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?;
// Using separate host and port (convenient for IPv6)
let client = ClientBuilder::new(("fe80::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
impl ClientBuilder
Sourcepub fn new(target: impl Into<Target>, auth: impl Into<Auth>) -> Self
pub fn new(target: impl Into<Target>, auth: impl Into<Auth>) -> Self
Create a new client builder.
§Arguments
target- The target address. Accepts a string (e.g.,"192.168.1.1"or"192.168.1.1:161"), a(host, port)tuple (e.g.,("fe80::1", 161)), or aSocketAddr. Port defaults to 161 if not specified. IPv6 addresses are supported as bare (::1) or bracketed ([::1]:162) forms.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 separate host and port
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"));Sourcepub fn timeout(self, timeout: Duration) -> Self
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));Sourcepub fn retry(self, retry: impl Into<Retry>) -> Self
pub fn retry(self, retry: impl Into<Retry>) -> Self
Set the retry configuration (default: 3 retries, 1-second delay).
On timeout, the client resends the request up to this many times before
returning an error. Timeout retransmissions are disabled for TCP (which
handles reliability at the transport layer). SNMPv3 protocol correction
is independent of this setting and remains available with
Retry::none and on reliable transports.
§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));Sourcepub fn max_oids_per_request(self, max: usize) -> Self
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. Values must be greater than zero.
§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);Sourcepub fn max_repetitions(self, max: u32) -> Self
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);Sourcepub fn walk_mode(self, mode: WalkMode) -> Self
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/v3WalkMode::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);Sourcepub fn oid_ordering(self, ordering: OidOrdering) -> Self
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);Sourcepub fn max_walk_results(self, limit: usize) -> Self
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);Set the persisted local authoritative engine state for V3 trap sending.
Per RFC 3412 Section 6.4, the sender is the authoritative engine for
trap PDUs. Required when sending V3 traps; not needed for V3 informs
(which use engine discovery against the receiver). Construct the value
with AuthoritativeEngine::install on first installation or
AuthoritativeEngine::restart on subsequent process starts.
§Example
use async_snmp::{Auth, AuthProtocol, ClientBuilder};
use async_snmp::v3::AuthoritativeEngine;
use std::convert::Infallible;
let engine = AuthoritativeEngine::install(b"my-engine-id".to_vec(), |_| {
Ok::<(), Infallible>(())
}).unwrap();
let builder = ClientBuilder::new(("192.168.1.1", 162),
Auth::usm("trapuser").auth(AuthProtocol::Sha256, "password"))
.local_authoritative_engine(engine);Sourcepub fn engine_cache(self, cache: Arc<EngineCache>) -> Self
pub fn engine_cache(self, cache: Arc<EngineCache>) -> Self
Set shared engine cache (V3 only, for polling many targets).
Allows multiple clients to share target-to-engine identity mappings and
per-authoritative-engine trusted time, reducing discovery requests and
keeping clients that reach the same engine coherent. Cache expiry affects
lookup by newly constructed clients; it does not replace an identity
already established by a live client. Use
Client::rediscover_engine for an
intentional identity replacement.
§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());Sourcepub fn strict_source(self, strict: bool) -> Self
pub fn strict_source(self, strict: bool) -> Self
Require UDP responses to originate from the configured target.
By default, UDP responses are matched by request ID and a source
mismatch only logs a warning, which permits multihomed agents to reply
from another address. Enabling this option drops off-target datagrams
while leaving the request pending for a response from the configured
target. The policy applies to discovery and ordinary exchanges made by
connect or build_with.
TCP is inherently connected to one peer. Clients constructed with a custom transport configure source policy on that transport instead.
Sourcepub fn allow_unauthenticated_v3_time_correction(self, allow: bool) -> Self
pub fn allow_unauthenticated_v3_time_correction(self, allow: bool) -> Self
Allow one packet-local correction from an unauthenticated SNMPv3
usmStatsNotInTimeWindows Report (default: false).
Some devices reply to an authenticated request with a noAuthNoPriv time-window Report, contrary to RFC 3414. When enabled, a correlated Report with the established engine ID and exact status shape may supply the boots/time tuple for one authenticated corrected packet. The tuple is not written to live or shared trusted state. Only a subsequent authenticated, correlated, fully matched Response can advance trusted time normally.
Enabling this weakens spoof resistance: an attacker able to inject a
matching Report can choose the time fields on one outbound authenticated
packet. Use strict_source for UDP when the
device does not legitimately reply from another address.
Sourcepub async fn connect(self) -> Result<Client<UdpHandle>>
pub async fn connect(self) -> Result<Client<UdpHandle>>
Connect via UDP (default).
Creates a new UDP socket for this client. Each call allocates a separate socket and recv loop.
To share a single socket across multiple clients, use
build_with() instead.
§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?;Sourcepub async fn build_with(
self,
transport: &UdpTransport,
) -> Result<Client<UdpHandle>>
pub async fn build_with( self, transport: &UdpTransport, ) -> Result<Client<UdpHandle>>
Build a client using a shared UDP transport.
Creates a handle for the builder’s target address from the given transport. All clients sharing a transport use one socket and one recv loop.
§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).await?;
let client2 = ClientBuilder::new("192.168.1.2:161", Auth::v2c("public"))
.build_with(&transport).await?;Sourcepub async fn connect_tcp(self) -> Result<Client<TcpTransport>>
pub async fn connect_tcp(self) -> Result<Client<TcpTransport>>
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.
For advanced TCP configuration (connection timeout, keepalive, buffer
sizes), construct a TcpTransport directly and use Client::new().
§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?;Trait Implementations§
Auto Trait Implementations§
impl !Freeze for ClientBuilder
impl RefUnwindSafe for ClientBuilder
impl Send for ClientBuilder
impl Sync for ClientBuilder
impl Unpin for ClientBuilder
impl UnsafeUnpin for ClientBuilder
impl UnwindSafe for ClientBuilder
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more