📄 ax_ma.c
字号:
envoy_ax_ma_cleanup_session_mth(bits32_t session_id, bits8_t err_stat){ENVOY_AX_SESSION_T *sp;int err_ret;sp = ax_session_find_index(session_id, &err_ret);if (sp) { (void) ax_session_remove(sp); ax_ma_cleanup_session(sp, err_stat); return(0); }return(1);}/********************************************************************************* envoy_ax_ma_cleanup_sessions - clean up sessions associated with a connection* SYNOPSIS** \cs* int envoy_ax_ma_cleanup_sessions* (* ptr_t cookie, * bits8_t err_stat * )* \ce** DESCRIPTION** This routine walks through the data structures to clean up all sessions that * were associated with a connection. This routine verifies that this is the * correct connection by calling 'ENVOY_AX_COOKIE_CMP() 'to determine whether * <cookie> matches the saved information block given to envoy_ax_sa_handler(). * It checks each connection listed for this session until it find a match.** PARAMETERS* \is* \i <cookie>* Specify the connection.* \i <err_stat>* Specify an error status code. If this value is nonzero, this routine attempts * to send a close message to the subagents before removing the sessions. The * close message uses <err_stat> as the reason for closing.* \ie** RETURNS: If successful, this routine returns 0. Otherwise, it returns 1. * Failures are often associated with problems with the locking code.** ERRNO: N/A** SEE ALSO: 'ENVOY_AX_COOKIE_CMP(),' envoy_ax_ma_handler(), * envoy_ax_sa_session_loss()*//********************************************************************************* envoy_ax_ma_handler - process packets for AgentX master agents* SYNOPSIS** \cs* void envoy_ax_ma_handler* ( * bits8_t * pkt_str, * ALENGTH_T pkt_len, * ENVOY_AX_SA_SB_T * sasb, * ENVOY_AX_ADMIN_T * admin_rtn, * ENVOY_AX_SEND_T * send_rtn, * ENVOY_AX_ERROR_T * error_rtn, * ptr_t send_cookie * )* \ce** DESCRIPTION** This routine is the main processing routine for an AgentX master agent. If * you use a packet-based transport layer, you can call this routine directly * from the user code. If you use a stream-based layer, it is more convenient to * use envoy_ax_chunk_handler().* If the incoming packet is a response to a query, this routine integrates the * information into the SNMP packet and continues to process the packet.* If the incoming packet is a subagent request, this routine attempts to * perform the desired action and uses the completion routines to communicate * with the user-supplied code.** PARAMETERS* \is* \i <*pkt_str>* Specify the packet to be processed.* \i <pkt_len>* Specify the length in bytes of the packet to be processed.* \i <*sasb>* Specify the subagent state block associated with the subagent. This field is * not used by this routine. It is included for compatibility with * envoy_ax_sa_handler(), the subagent handler.* \i <*admin_rtn>* Specify a customer-provided routine that is called when an 'OPEN' PDU * establishes that the session is open or when an AgentX 'TRAP' PDU is * received.* \i <*send_rtn>* Specify a customer-provided routine that is called to send packets.* \i <*error_rtn>* Specify a customer-provided routine that is called to respond to errors.* \i <send_cookie>* Specify the cookie, which would contain an address for UDP or a pointer to a * TCP block.* \ie** RETURNS: None.** ERRNO: N/A** SEE ALSO: envoy_ax_chunk_handler(), envoy_ax_ma_cleanup_sessions(), * envoy_ax_sa_handler()*//********************************************************************************* envoy_ax_pkt_allocate - allocate and initialize an AgentX packet structure* SYNOPSIS** \cs* ENVOY_AX_PKT_T * envoy_ax_pkt_allocate()* \ce** DESCRIPTION** This routine attempts to allocate space for an AgentX packet structure and * initialize the structure to a known empty state.** PARAMETERS* None.** RETURNS: If successful, this routine returns a pointer to the allocated * structure. Otherwise, it returns 0.** ERRNO: N/A** SEE ALSO: envoy_ax_pkt_init()*/int envoy_ax_ma_cleanup_sessions(ptr_t handle, bits8_t err_stat){ENVOY_AX_SESSION_T *sp;int err_ret = 0;while((sp = ax_session_find_handle(handle, &err_ret)) != 0) { (void) ax_session_remove(sp); ax_ma_cleanup_session(sp, err_stat); }return(err_ret);}static bits32_t ax_make_cb(SNMP_PKT_T *pktp, VB_T *vbp, int tcount){AX_CB_T *ctl_blk;ctl_blk = (AX_CB_T *)SNMP_memory_alloc(sizeof(AX_CB_T));if (ctl_blk == 0) return(0);/* Try to get the infrastructure lock */#if INSTALL_ENVOY_SNMP_LOCKif (ENVOY_SNMP_GET_WRITE_LOCK(SNMP_infrastructure_lock)) { BUG(BUG_ENVOY_LOCKING, BUG_CONTINUABLE, 0, (BUG_OUT, "ax_make_cb: infrastructure lock is broken", 0)); return(0); }#endif/* 0 is a reserved id so make sure we don't give it out */if (ax_reqid == 0) ax_reqid++;/* install the info into the state block */ctl_blk->reqid = ax_reqid++;ctl_blk->pktp = pktp;ctl_blk->vbp = vbp;ctl_blk->count = tcount;/* and put the state block into the state list */ctl_blk->next = first_axcb;first_axcb = ctl_blk;ENVOY_SNMP_RELEASE_WRITE_LOCK(SNMP_infrastructure_lock);return(ctl_blk->reqid);}static AX_CB_T * ax_uninstall_cb(bits32_t reqid){AX_CB_T *cbp = 0, **pcbp;/* Try to get the infrastructure lock */#if INSTALL_ENVOY_SNMP_LOCKif (ENVOY_SNMP_GET_WRITE_LOCK(SNMP_infrastructure_lock)) { BUG(BUG_ENVOY_LOCKING, BUG_CONTINUABLE, 0, (BUG_OUT, "ax_uninstall_cb: infrastructure lock is broken", 0)); return(0); }#endiffor(pcbp = &first_axcb; *pcbp; pcbp = &(*pcbp)->next) if ((*pcbp)->reqid == reqid) { cbp = *pcbp; *pcbp = cbp->next; break; }ENVOY_SNMP_RELEASE_WRITE_LOCK(SNMP_infrastructure_lock);return(cbp);}/****************************************************************************NAME: ax_timerPURPOSE: Routine to be called by the timer code to clean up the agentx request list on timeouts. The cookie is the index into the agentx request list, we look up the index and remove the control block.PARAMETERS: struct envoy_timer * the timer control block void * the cookie pointerRETURNS: void****************************************************************************/static void ax_timer(ENVOY_TIMER_T *tm, void *cookiep){AX_CB_T *cbp;VB_T *vbp;SNMP_PKT_T *pktp;ENVOY_AX_SESSION_T *session;int err_ret; /* try to get the control block, we need to do this before we clean the timer struct as cookiep will disappear with the timer */cbp = ax_uninstall_cb(((ENVOY_TIMER_32_T *)cookiep)->id);/* clean up the timer struct */SNMP_memory_free(cookiep);if (cbp == 0) return;vbp = cbp->vbp;pktp = cbp->pktp;/* clean up the structure */SNMP_memory_free(cbp);/* We want to note that the AgentX session had a timeout and * close the session if this exceeds our tolerance. */if (SNMP_AX_TIMEOUT_COUNT != 0) { session = ax_session_find_index(vbp->vb_ml.ml_leaf->session_id, &err_ret); if (session) { /* increment the number of consecutive timeouts */ session->timeout_count++; if (session->timeout_count >= SNMP_AX_TIMEOUT_COUNT) { (void) ax_session_remove(session); /* clean up session but don't send a close to the subagent */ ax_ma_cleanup_session(session, 0); } else ax_session_release(session); } }#if INSTALL_ENVOY_CONTINUE_REENTRANT/* If necessary we acquire the packet continue write lock here It gets freed when we call the continue routine. We don't have any good options if we can't get the lock. The user shouldn't do that, if they do we generate a bug report and if they don't handle that we return which is the least bad thing to do. */if (ENVOY_SNMP_GET_WRITE_LOCK(pktp->continue_lock)) { BUG(BUG_ENVOY_LOCKING, BUG_FATAL, 0, (BUG_OUT, "ax_timer(): packet continue lock is broken", 0)); return; }#endif/* now tag the varbinds correctly and continue */switch(pktp->pdu_type) { case GET_REQUEST_PDU: getproc_error(pktp, vbp, GEN_ERR); break; case GET_NEXT_REQUEST_PDU: case GET_BULK_REQUEST_PDU: nextproc_error(pktp, vbp, GEN_ERR); break; case SET_REQUEST_PDU: if (vbp->vb_flags & VFLAG_UNDO_STARTED) undoproc_error(pktp, vbp, UNDO_FAILED); else if (vbp->vb_flags & VFLAG_SET_STARTED) setproc_error(pktp, vbp, COMMIT_FAILED); else testproc_error(pktp, vbp, GEN_ERR); break; }SNMP_Continue(pktp);return;}/****************************************************************************NAME: group_by_sessionPURPOSE: Grouping routine for use with agentx method routines scan through the varbind list for any vbs that have an agentx getproc and the same session id as the given varbind Any varbinds that match are linked to the first one but they aren't marked as processed. NOTE: we don't check to see if any routines have been started or finished as we're the only ones who should be operating with these routines.PARAMETERS: SNMP_PKT_T * the packet being processed VB_T * the varbind being processedRETURNS: void****************************************************************************/static void group_by_session(SNMP_PKT_T *pktp, VB_T *first_vbp){VBL_T *vblp;VB_T *last_vbp, *vbp, *list;bits32_t session_id;#if INSTALL_ENVOY_SNMP_VERSION_1if (pktp->pdu_type == TRAP_PDU) vblp = &(pktp->pdu.trap_pdu.trap_vbl); else#endif /* find the last vblp, which is always the one we are working on */ for (vblp = &(pktp->pdu.std_pdu.std_vbl); vblp->vblp; vblp = vblp->vblp) ; list = first_vbp;list->vb_link = 0;session_id = first_vbp->vb_ml.ml_leaf->session_id;for (last_vbp = &vblp->vblist[vblp->vbl_count], vbp = first_vbp + 1; vbp < last_vbp; vbp++) { /* find varbinds with the same getproc which aren't already in use */ if (vbp->vb_ml.ml_leaf && ((vbp->vb_flags & (VFLAG_SET_STARTED | VFLAG_SET_DONE | VFLAG_TEST_STARTED | VFLAG_TEST_DONE)) == 0) && (vbp->vb_ml.ml_leaf->getproc == (ASY_GETPROC_T *)ax_getproc) && (vbp->vb_ml.ml_leaf->session_id == session_id)) { /* link onto the list */ list->vb_link = vbp; list = vbp; vbp->vb_link = 0; } }}/****************************************************************************NAME: ax_transfer_valuePURPOSE: Transfer a value from one vbp to another vbp. Generally this will be used to transfer the information returned from a sub agent to the packet in the master agent.PARAMETERS: SNMP_PKT_T * Packet we are processing VB_T * Variable to put the information into VB_T * Variable to take the information fromRETURNS: int 0 success, 1 illegal type flag****************************************************************************//*ARGSUSED*/static int ax_transfer_value(SNMP_PKT_T *pktp, VB_T *vbp, VB_T *rvbp){bits8_t data_type;data_type = rvbp->vb_data_flags_n_type;switch (data_type) { case VT_NUMBER: getproc_got_int32(pktp, vbp, rvbp->value_u.v_number); break; case VT_COUNTER: case VT_GAUGE: case VT_TIMETICKS: case VT_UINTEGER32: getproc_got_uint32(pktp, vbp, rvbp->value_u.v_counter, data_type); break; case VT_STRING: case VT_OPAQUE: getproc_got_string(pktp, vbp, EBufferUsed(&(rvbp->value_u.v_string)), EBufferStart(&(rvbp->value_u.v_string)), rvbp->value_u.v_string.bflags, data_type); EBufferInitialize(&(rvbp->value_u.v_string)); break; case VT_OBJECT: getproc_got_object_id(pktp, vbp, rvbp->value_u.v_object.num_components, rvbp->value_u.v_object.component_list, 1); init_object_id(&(rvbp->value_u.v_object)); break; case VT_EMPTY:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -