📄 stash_cache.c
字号:
#include <net-snmp/net-snmp-config.h>#if HAVE_STRING_H#include <string.h>#else#include <strings.h>#endif#include <net-snmp/net-snmp-includes.h>#include <net-snmp/agent/net-snmp-agent-includes.h>#include <net-snmp/agent/stash_cache.h>#include <net-snmp/agent/stash_to_next.h>extern NetsnmpCacheLoad _netsnmp_stash_cache_load;extern NetsnmpCacheFree _netsnmp_stash_cache_free; /** @defgroup stash_cache stash_cache * Automatically caches data for certain handlers. * This handler caches data in an optimized way which may aleviate * the need for the lower level handlers to perform as much * optimization. Specifically, somewhere in the lower level handlers * must be a handler that supports the MODE_GET_STASH operation. * Note that the table_iterator helper supports this. * @ingroup handler * @{ */netsnmp_stash_cache_info *netsnmp_get_new_stash_cache(void){ netsnmp_stash_cache_info *cinfo; cinfo = SNMP_MALLOC_TYPEDEF(netsnmp_stash_cache_info); cinfo->cache_length = 30; return cinfo;}/** returns a stash_cache handler that can be injected into a given * handler chain (with the specified timeout and root OID values), * but *only* if that handler chain explicitly supports stash cache processing. */netsnmp_mib_handler *netsnmp_get_timed_bare_stash_cache_handler(int timeout, oid *rootoid, size_t rootoid_len){ netsnmp_mib_handler *handler; netsnmp_cache *cinfo; cinfo = netsnmp_cache_create( timeout, _netsnmp_stash_cache_load, _netsnmp_stash_cache_free, rootoid, rootoid_len ); if (!cinfo) return NULL; handler = netsnmp_cache_handler_get( cinfo ); if (!handler) { free(cinfo); return NULL; } handler->next = netsnmp_create_handler("stash_cache", netsnmp_stash_cache_helper); if (!handler->next) { netsnmp_handler_free(handler); free(cinfo); return NULL; } handler->myvoid = cinfo; return handler;}/** returns a single stash_cache handler that can be injected into a given * handler chain (with a fixed timeout), but *only* if that handler chain * explicitly supports stash cache processing. */netsnmp_mib_handler *netsnmp_get_bare_stash_cache_handler(void){ return netsnmp_get_timed_bare_stash_cache_handler( 30, NULL, 0 );}/** returns a stash_cache handler sub-chain that can be injected into a given * (arbitrary) handler chain, using a fixed cache timeout. */netsnmp_mib_handler *netsnmp_get_stash_cache_handler(void){ netsnmp_mib_handler *handler = netsnmp_get_bare_stash_cache_handler(); if (handler && handler->next) { handler->next->next = netsnmp_get_stash_to_next_handler(); } return handler;}/** returns a stash_cache handler sub-chain that can be injected into a given * (arbitrary) handler chain, using a configurable cache timeout. */netsnmp_mib_handler *netsnmp_get_timed_stash_cache_handler(int timeout, oid *rootoid, size_t rootoid_len){ netsnmp_mib_handler *handler = netsnmp_get_timed_bare_stash_cache_handler(timeout, rootoid, rootoid_len); if (handler && handler->next) { handler->next->next = netsnmp_get_stash_to_next_handler(); } return handler;}/** extracts a pointer to the stash_cache info from the reqinfo structure. */netsnmp_oid_stash_node **netsnmp_extract_stash_cache(netsnmp_agent_request_info *reqinfo){ return netsnmp_agent_get_list_data(reqinfo, STASH_CACHE_NAME);}/** @internal Implements the stash_cache handler */intnetsnmp_stash_cache_helper(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests){ netsnmp_cache *cache; netsnmp_stash_cache_info *cinfo; netsnmp_oid_stash_node *cnode; netsnmp_variable_list *cdata; netsnmp_request_info *request; DEBUGMSGTL(("helper:stash_cache", "Got request\n")); cache = netsnmp_cache_reqinfo_extract( reqinfo, reginfo->handlerName ); cinfo = (netsnmp_stash_cache_info *) cache->magic; switch (reqinfo->mode) { case MODE_GET: DEBUGMSGTL(("helper:stash_cache", "Processing GET request\n")); for(request = requests; request; request = request->next) { cdata = netsnmp_oid_stash_get_data(cinfo->cache, requests->requestvb->name, requests->requestvb->name_length); if (cdata && cdata->val.string && cdata->val_len) { DEBUGMSGTL(("helper:stash_cache", "Found cached GET varbind\n")); DEBUGMSGOID(("helper:stash_cache", cdata->name, cdata->name_length)); DEBUGMSG(("helper:stash_cache", "\n")); snmp_set_var_typed_value(request->requestvb, cdata->type, cdata->val.string, cdata->val_len); } } return SNMP_ERR_NOERROR; break; case MODE_GETNEXT: DEBUGMSGTL(("helper:stash_cache", "Processing GETNEXT request\n")); for(request = requests; request; request = request->next) { cnode = netsnmp_oid_stash_getnext_node(cinfo->cache, requests->requestvb->name, requests->requestvb->name_length); if (cnode && cnode->thedata) { cdata = cnode->thedata; if (cdata->val.string && cdata->name && cdata->name_length) { DEBUGMSGTL(("helper:stash_cache", "Found cached GETNEXT varbind\n")); DEBUGMSGOID(("helper:stash_cache", cdata->name, cdata->name_length)); DEBUGMSG(("helper:stash_cache", "\n")); snmp_set_var_typed_value(request->requestvb, cdata->type, cdata->val.string, cdata->val_len); snmp_set_var_objid(request->requestvb, cdata->name, cdata->name_length); } } } return SNMP_ERR_NOERROR; break; default: cinfo->cache_valid = 0; return netsnmp_call_next_handler(handler, reginfo, reqinfo, requests); } return SNMP_ERR_GENERR; /* should never get here */}/** updates a given cache depending on whether it needs to or not. */int_netsnmp_stash_cache_load( netsnmp_cache *cache, void *magic ){ netsnmp_mib_handler *handler = cache->cache_hint->handler; netsnmp_handler_registration *reginfo = cache->cache_hint->reginfo; netsnmp_agent_request_info *reqinfo = cache->cache_hint->reqinfo; netsnmp_request_info *requests = cache->cache_hint->requests; netsnmp_stash_cache_info *cinfo = (netsnmp_stash_cache_info*) magic; int old_mode; int ret; if (!cinfo) { cinfo = netsnmp_get_new_stash_cache(); cache->magic = cinfo; } /* change modes to the GET_STASH mode */ old_mode = reqinfo->mode; reqinfo->mode = MODE_GET_STASH; netsnmp_agent_add_list_data(reqinfo, netsnmp_create_data_list(STASH_CACHE_NAME, &cinfo->cache, NULL)); /* have the next handler fill stuff in and switch modes back */ ret = netsnmp_call_next_handler(handler->next, reginfo, reqinfo, requests); reqinfo->mode = old_mode; return ret;}void_netsnmp_stash_cache_free( netsnmp_cache *cache, void *magic ){ netsnmp_stash_cache_info *cinfo = (netsnmp_stash_cache_info*) magic; netsnmp_oid_stash_free(&cinfo->cache, (NetSNMPStashFreeNode *) snmp_free_var); return;}/** initializes the stash_cache helper which then registers a stash_cache * handler as a run-time injectable handler for configuration file * use. */voidnetsnmp_init_stash_cache_helper(void){ netsnmp_register_handler_by_name("stash_cache", netsnmp_get_stash_cache_handler());}/** @} */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -