Temporarily add go-agentx (w/ fixes to lexico ordering)
This commit is contained in:
185
go-agentx/session.go
Normal file
185
go-agentx/session.go
Normal 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())
|
||||
}
|
Reference in New Issue
Block a user