MibHandler

Trait MibHandler 

Source
pub trait MibHandler:
    Send
    + Sync
    + 'static {
    // Required methods
    fn get<'a>(
        &'a self,
        ctx: &'a RequestContext,
        oid: &'a Oid,
    ) -> BoxFuture<'a, GetResult>;
    fn get_next<'a>(
        &'a self,
        ctx: &'a RequestContext,
        oid: &'a Oid,
    ) -> BoxFuture<'a, GetNextResult>;

    // Provided methods
    fn test_set<'a>(
        &'a self,
        _ctx: &'a RequestContext,
        _oid: &'a Oid,
        _value: &'a Value,
    ) -> BoxFuture<'a, SetResult> { ... }
    fn commit_set<'a>(
        &'a self,
        _ctx: &'a RequestContext,
        _oid: &'a Oid,
        _value: &'a Value,
    ) -> BoxFuture<'a, SetResult> { ... }
    fn undo_set<'a>(
        &'a self,
        _ctx: &'a RequestContext,
        _oid: &'a Oid,
        _value: &'a Value,
    ) -> BoxFuture<'a, ()> { ... }
    fn handles(&self, registered_prefix: &Oid, oid: &Oid) -> bool { ... }
}
Expand description

Handler for SNMP MIB operations.

Implement this trait to provide values for a subtree of OIDs. Register handlers with AgentBuilder::handler() using a prefix OID.

§SET Operations

SET operations use a two-phase commit protocol for RFC 3416 atomicity:

  1. Test phase: test_set is called for ALL varbinds before any commits. If any test fails, no changes are made.

  2. Commit phase: commit_set is called for each varbind in order. If a commit fails, undo_set is called for all previously committed varbinds (in reverse order).

§Bounds

The 'static bound is required because handlers are stored as Arc<dyn MibHandler> within the agent. This allows the agent to hold handlers for its entire lifetime without lifetime annotations. In practice, most handlers naturally satisfy this bound.

§Thread Safety

Handlers must be Send + Sync because the agent may process requests concurrently from multiple tasks.

§Example

use async_snmp::handler::{MibHandler, RequestContext, GetResult, GetNextResult, BoxFuture};
use async_snmp::{Oid, Value, VarBind, oid};

struct MyHandler;

impl MibHandler for MyHandler {
    fn get<'a>(&'a self, ctx: &'a RequestContext, oid: &'a Oid) -> BoxFuture<'a, GetResult> {
        Box::pin(async move {
            if oid == &oid!(1, 3, 6, 1, 4, 1, 99999, 1, 0) {
                return GetResult::Value(Value::Integer(42));
            }
            GetResult::NoSuchObject
        })
    }

    fn get_next<'a>(&'a self, ctx: &'a RequestContext, oid: &'a Oid) -> BoxFuture<'a, GetNextResult> {
        Box::pin(async move {
            let my_oid = oid!(1, 3, 6, 1, 4, 1, 99999, 1, 0);
            if oid < &my_oid {
                return GetNextResult::Value(VarBind::new(my_oid, Value::Integer(42)));
            }
            GetNextResult::EndOfMibView
        })
    }
}

Required Methods§

Source

fn get<'a>( &'a self, ctx: &'a RequestContext, oid: &'a Oid, ) -> BoxFuture<'a, GetResult>

Handle a GET request for a specific OID.

Return GetResult::Value if the OID exists, GetResult::NoSuchObject if the object type is not implemented, or GetResult::NoSuchInstance if the object type exists but this specific instance doesn’t.

See GetResult documentation for details on when to use each variant.

Source

fn get_next<'a>( &'a self, ctx: &'a RequestContext, oid: &'a Oid, ) -> BoxFuture<'a, GetNextResult>

Handle a GETNEXT request.

Return GetNextResult::Value with the lexicographically next OID and value after oid, or GetNextResult::EndOfMibView if there are no more OIDs in this handler’s subtree.

Provided Methods§

Source

fn test_set<'a>( &'a self, _ctx: &'a RequestContext, _oid: &'a Oid, _value: &'a Value, ) -> BoxFuture<'a, SetResult>

Test if a SET operation would succeed (phase 1 of two-phase commit).

Called for ALL varbinds before any commits. Must NOT modify state. Return SetResult::Ok if the SET would succeed, or an appropriate error otherwise.

Default implementation returns NotWritable (read-only handler).

Source

fn commit_set<'a>( &'a self, _ctx: &'a RequestContext, _oid: &'a Oid, _value: &'a Value, ) -> BoxFuture<'a, SetResult>

Commit a SET operation (phase 2 of two-phase commit).

Only called after ALL test_set calls succeed. Should apply the change. If this fails, undo_set will be called for all previously committed varbinds in this request.

Default implementation returns NotWritable (read-only handler).

Source

fn undo_set<'a>( &'a self, _ctx: &'a RequestContext, _oid: &'a Oid, _value: &'a Value, ) -> BoxFuture<'a, ()>

Undo a committed SET operation (rollback on partial failure).

Called if a later commit_set fails. Should restore the previous value. This is best-effort: if undo fails, log a warning but continue.

Default implementation does nothing (no rollback support).

Source

fn handles(&self, registered_prefix: &Oid, oid: &Oid) -> bool

Check if this handler handles the given OID prefix.

Default implementation returns true if the OID starts with the registered prefix or is lexicographically before it (for GETNEXT support). Override for more complex matching.

Implementors§