Temporarily add go-agentx (w/ fixes to lexico ordering)

This commit is contained in:
Pim van Pelt
2025-06-09 17:14:28 +02:00
parent 824496c402
commit 771cc6ff48
45 changed files with 2477 additions and 0 deletions

185
go-agentx/session.go Normal file
View File

@ -0,0 +1,185 @@
// Copyright 2018 The agentx authors
// Licensed under the LGPLv3 with static-linking exception.
// See LICENCE file for details.
package agentx
import (
"errors"
"fmt"
"log"
"time"
"github.com/posteo/go-agentx/pdu"
"github.com/posteo/go-agentx/value"
)
// Session defines an agentx session.
type Session struct {
Handler Handler
client *Client
sessionID uint32
timeout time.Duration
openRequestPacket *pdu.HeaderPacket
registerRequestPacket *pdu.HeaderPacket
}
// ID returns the session id.
func (s *Session) ID() uint32 {
return s.sessionID
}
// Register registers the client under the provided rootID with the provided priority
// on the master agent.
func (s *Session) Register(priority byte, baseOID value.OID) error {
if s.registerRequestPacket != nil {
return fmt.Errorf("session is already registered")
}
requestPacket := &pdu.Register{}
requestPacket.Timeout.Duration = s.timeout
requestPacket.Timeout.Priority = priority
requestPacket.Subtree.SetIdentifier(baseOID)
request := &pdu.HeaderPacket{Header: &pdu.Header{Type: pdu.TypeRegister}, Packet: requestPacket}
response := s.request(request)
if err := checkError(response); err != nil {
return err
}
s.registerRequestPacket = request
return nil
}
// Unregister removes the registration for the provided subtree.
func (s *Session) Unregister(priority byte, baseOID value.OID) error {
if s.registerRequestPacket == nil {
return fmt.Errorf("session is not registered")
}
requestPacket := &pdu.Unregister{}
requestPacket.Timeout.Duration = s.timeout
requestPacket.Timeout.Priority = priority
requestPacket.Subtree.SetIdentifier(baseOID)
request := &pdu.HeaderPacket{Header: &pdu.Header{}, Packet: requestPacket}
response := s.request(request)
if err := checkError(response); err != nil {
return err
}
s.registerRequestPacket = nil
return nil
}
// Close tears down the session with the master agent.
func (s *Session) Close() error {
requestPacket := &pdu.Close{Reason: pdu.ReasonShutdown}
response := s.request(&pdu.HeaderPacket{Header: &pdu.Header{}, Packet: requestPacket})
if err := checkError(response); err != nil {
return err
}
return nil
}
func (s *Session) open(nameOID value.OID, name string) error {
requestPacket := &pdu.Open{}
requestPacket.Timeout.Duration = s.timeout
requestPacket.ID.SetIdentifier(nameOID)
requestPacket.Description.Text = name
request := &pdu.HeaderPacket{Header: &pdu.Header{Type: pdu.TypeOpen}, Packet: requestPacket}
response := s.request(request)
if err := checkError(response); err != nil {
return err
}
s.sessionID = response.Header.SessionID
s.openRequestPacket = request
return nil
}
func (s *Session) reopen() error {
if s.openRequestPacket != nil {
response := s.request(s.openRequestPacket)
if err := checkError(response); err != nil {
return err
}
s.sessionID = response.Header.SessionID
}
if s.registerRequestPacket != nil {
response := s.request(s.registerRequestPacket)
if err := checkError(response); err != nil {
return err
}
}
return nil
}
func (s *Session) request(hp *pdu.HeaderPacket) *pdu.HeaderPacket {
hp.Header.SessionID = s.sessionID
return s.client.request(hp)
}
func (s *Session) handle(request *pdu.HeaderPacket) *pdu.HeaderPacket {
responseHeader := &pdu.Header{}
responseHeader.SessionID = request.Header.SessionID
responseHeader.TransactionID = request.Header.TransactionID
responseHeader.PacketID = request.Header.PacketID
responsePacket := &pdu.Response{}
switch requestPacket := request.Packet.(type) {
case *pdu.Get:
if s.Handler == nil {
log.Printf("warning: no handler for session specified")
responsePacket.Variables.Add(requestPacket.GetOID(), pdu.VariableTypeNull, nil)
} else {
oid, t, v, err := s.Handler.Get(requestPacket.GetOID())
if err != nil {
log.Printf("error while handling packet: %v", err)
responsePacket.Error = pdu.ErrorProcessing
}
if oid == nil {
responsePacket.Variables.Add(requestPacket.GetOID(), pdu.VariableTypeNoSuchObject, nil)
} else {
responsePacket.Variables.Add(oid, t, v)
}
}
case *pdu.GetNext:
if s.Handler == nil {
log.Printf("warning: no handler for session specified")
} else {
for _, sr := range requestPacket.SearchRanges {
oid, t, v, err := s.Handler.GetNext(sr.From.GetIdentifier(), (sr.From.Include == 1), sr.To.GetIdentifier())
if err != nil {
log.Printf("error while handling packet: %v", err)
responsePacket.Error = pdu.ErrorProcessing
}
if oid == nil {
responsePacket.Variables.Add(sr.From.GetIdentifier(), pdu.VariableTypeEndOfMIBView, nil)
} else {
responsePacket.Variables.Add(oid, t, v)
}
}
}
default:
log.Printf("cannot handle unrequested packet: %v", request)
responsePacket.Error = pdu.ErrorProcessing
}
return &pdu.HeaderPacket{Header: responseHeader, Packet: responsePacket}
}
func checkError(hp *pdu.HeaderPacket) error {
response, ok := hp.Packet.(*pdu.Response)
if !ok {
return nil
}
if response.Error == pdu.ErrorNone {
return nil
}
return errors.New(response.Error.String())
}