📄 ax_index.c
字号:
for(context = ax_context_next(0); context; context = ax_context_next(context)){ for(tnode = TREE_GetNext(context->indexroot, 0); tnode; tnode = TREE_GetNext(context->indexroot, tnode)) { if (TREE_Extract(tnode, (ptr_t *)&ihdr)) continue; for (idata = ihdr->data; idata; idata = idata->next) if (idata->session_id == session_id) idata->session_id = 0; } }}/****************************************************************************NAME: ax_ma_index_deallocatePURPOSE: mark any indexes owned by this session as available for reuse We copy the pointers for the varbind list from the decoded packet to the reply packet and don't zero them in the decoded packet. We can do this because the calling routine will free the decoded packet but not the reply packet.PARAMETERS: ENVOY_AX_PKT_T * decoded packet to process ENVOY_AX_PKT_T * reply packet ENVOY_AX_CONTEXT_T * context structure, contains the index root RETURNS: void****************************************************************************/void ax_ma_index_deallocate(ENVOY_AX_PKT_T *ax_pkt, ENVOY_AX_PKT_T *reply_pkt, ENVOY_AX_CONTEXT_T *context){TREENODE_T *tnode;ENVOY_AX_INDEX_HDR_T *ihdr;ENVOY_AX_INDEX_DATA_T *idata;VB_T *vbp;int count, length;reply_pkt->data.proc_data.vbl_str.vbl_count = ax_pkt->data.proc_data.vbl_str.vbl_count;reply_pkt->data.proc_data.vbl_str.vblist = ax_pkt->data.proc_data.vbl_str.vblist;/* do the lookup twice to avoid chaging things if there are any errors */for(vbp = ax_pkt->data.proc_data.vbl_str.vblist, count = 0; count < ax_pkt->data.proc_data.vbl_str.vbl_count; vbp++, count++) { tnode = TREE_Get(context->indexroot, vbp->vb_obj_id.component_list, vbp->vb_obj_id.num_components, &length); if (tnode && (length == vbp->vb_obj_id.num_components) && (TREE_Extract(tnode, (ptr_t *)&ihdr) == 0) && (ihdr->type == vbp->vb_data_flags_n_type) && ((idata = ax_ma_find_index(ihdr->data, vbp, ax_pkt->session_id)) != 0)) { vbp->vb_priv = idata; continue; } reply_pkt->error_stat = ENVOY_AX_INDEX_NOT_ALLOCATED; reply_pkt->error_index = count + 1; return; }for(vbp = ax_pkt->data.proc_data.vbl_str.vblist, count = ax_pkt->data.proc_data.vbl_str.vbl_count; count; vbp++, count--) { ((ENVOY_AX_INDEX_DATA_T *)(vbp->vb_priv))->session_id = 0; }return;}/****************************************************************************NAME: ax_ma_index_allocatePURPOSE: try to add the indexes from the var bind list into the index tree. We copy the pointers for the varbind list from the decoded packet to the reply packet and don't zero them in the decoded packet. We can do this because the calling routine will free the decoded packet but not the reply packet. We can also use static pointers to any indexes we create as the packet will be sent before we release any locks we hold.PARAMETERS: ENVOY_AX_PKT_T * decoded packet to process ENVOY_AX_PKT_T * reply packet ENVOY_AX_CONTEXT_T * context structure, contains the index root RETURNS: void****************************************************************************/void ax_ma_index_allocate(ENVOY_AX_PKT_T *ax_pkt, ENVOY_AX_PKT_T *reply_pkt, ENVOY_AX_CONTEXT_T *context){VB_T *vbp;int count, stat = 0, length;TREENODE_T *tnode, *bptr;ENVOY_AX_INDEX_HDR_T *ihdr;ENVOY_AX_INDEX_DATA_T *idata, **idatap;bits8_t any_flag;any_flag = ax_pkt->flags & (ENVOY_AX_BIT_NEW_INDEX | ENVOY_AX_BIT_ANY_INDEX);/*sar protocol violation if both bits on?*/reply_pkt->data.proc_data.vbl_str.vbl_count = ax_pkt->data.proc_data.vbl_str.vbl_count;reply_pkt->data.proc_data.vbl_str.vblist = ax_pkt->data.proc_data.vbl_str.vblist;if (ax_pkt->data.proc_data.vbl_str.vbl_count == 0) return;/* walk through the var bind list and try to add the requested indexes when we finish the loop we check and see if there were any errors if so we clean up any work that we did otherwise just return. 1) check the type for legality 2) find the leaf in the tree if it exists check the new type against the old type if it doesn't exist try to build it 3) deal with the index itself a) specified index - try to find a matching entry if we have one check to see if it's already in use if we don't have one try to build one b) any index - look through the list for an entry that isn't in use if we can't find one proceed to c - a new entry c) new index - look through the list for the first index that isn't named */for(vbp = ax_pkt->data.proc_data.vbl_str.vblist, count = 0; count < ax_pkt->data.proc_data.vbl_str.vbl_count; vbp++, count++) { switch (vbp->vb_data_flags_n_type) { case VT_NUMBER: case VT_STRING: case VT_OBJECT: case VT_IPADDRESS: break; default: reply_pkt->error_stat = ENVOY_AX_INDEX_WRONG_TYPE; reply_pkt->error_index = count + 1; break; } tnode = TREE_Get(context->indexroot, vbp->vb_obj_id.component_list, vbp->vb_obj_id.num_components, &length); /* we want the named leaf, not an ancestor */ if (tnode && (length != vbp->vb_obj_id.num_components)) tnode = 0; if (tnode) { if (TREE_Extract(tnode, (ptr_t *)&ihdr)) { reply_pkt->error_stat = GEN_ERR; break; } if (ihdr->type != vbp->vb_data_flags_n_type) { reply_pkt->error_stat = ENVOY_AX_INDEX_WRONG_TYPE; reply_pkt->error_index = count + 1; break; } } else { /* no leaf, so we need to build one */ ihdr = (ENVOY_AX_INDEX_HDR_T *) SNMP_memory_alloc(sizeof(ENVOY_AX_INDEX_HDR_T)); if (ihdr == 0) { reply_pkt->error_stat = GEN_ERR; break; } ihdr->type = vbp->vb_data_flags_n_type; ihdr->data = 0; if (TREE_Add(&context->indexroot, vbp->vb_obj_id.component_list, vbp->vb_obj_id.num_components, (ptr_t)ihdr, &bptr)) { SNMP_memory_free(ihdr); reply_pkt->error_stat = GEN_ERR; break; } vbp->ax_flags |= ENVOY_AX_FLAGS_CLEAN_LEAF; } /* find or build the entry */ if (any_flag == 0) { /* Use the specified index */ for (idatap = &ihdr->data; *idatap; idatap = &(*idatap)->next) { stat = ax_ma_compare_indexes(0, vbp, 0, *idatap); if (stat != 1) break; } if (*idatap && (stat == 0)) { if ((*idatap)->session_id) { reply_pkt->error_stat = ENVOY_AX_INDEX_ALREADY_ALLOCATED; reply_pkt->error_index = count + 1; break; } (*idatap)->session_id = ax_pkt->session_id; vbp->vb_priv = (*idatap); } else { idata = (ENVOY_AX_INDEX_DATA_T *) SNMP_memory_alloc(sizeof(ENVOY_AX_INDEX_DATA_T)); if (idata == 0) { reply_pkt->error_stat = GEN_ERR; reply_pkt->error_index = count + 1; break; } switch(vbp->vb_data_flags_n_type) { case VT_NUMBER: idata->data.bits32 = vbp->value_u.v_number; break; case VT_STRING: idata->data.string.length = EBufferUsed(&vbp->value_u.v_string); if (idata->data.string.length) { idata->data.string.buffer = SNMP_memory_alloc(idata->data.string.length); if (idata->data.string.buffer == 0) { SNMP_memory_free(idata); idata = 0; reply_pkt->error_stat = GEN_ERR; reply_pkt->error_index = count + 1; } else { MEMCPY(idata->data.string.buffer, EBufferStart(&vbp->value_u.v_string), idata->data.string.length); } } else idata->data.string.buffer = 0; break; case VT_OBJECT: if (clone_object_id(&vbp->value_u.v_object, &idata->data.objid)) { SNMP_memory_free(idata); idata = 0; reply_pkt->error_stat = GEN_ERR; reply_pkt->error_index = count + 1; } break; case VT_IPADDRESS: MEMCPY(&idata->data.ipaddr, &vbp->value_u.v_network_address, 4); break; } if (idata) { idata->session_id = ax_pkt->session_id; idata->next = *idatap; *idatap = idata; vbp->vb_priv = idata; vbp->ax_flags |= ENVOY_AX_FLAGS_CLEAN_INDEX; } else break; } } else { idata = 0; if (any_flag == ENVOY_AX_BIT_ANY_INDEX) { for(idata = ihdr->data; idata && idata->session_id; idata = idata->next) ; /* no body to the for loop */ if (idata) { idata->session_id = ax_pkt->session_id; vbp->vb_priv = idata; } } if (idata == 0) { /* find new index and build entry if it's an object id we stash a copy of the index in the search end area to move into the vbp value area if we succeed. */ idata = ax_ma_build_new_index(ihdr, vbp); if (idata == 0) { reply_pkt->error_stat = ENVOY_AX_INDEX_NONE_AVAILABLE; reply_pkt->error_index = count + 1; break; } idata->session_id = ax_pkt->session_id; vbp->vb_priv = idata; vbp->ax_flags |= ENVOY_AX_FLAGS_CLEAN_INDEX; } if ((vbp->vb_data_flags_n_type == VT_OBJECT) && (clone_object_id(&idata->data.objid, &vbp->ax_search_end))) { reply_pkt->error_stat = GEN_ERR; reply_pkt->error_index = count + 1; break; } } }/* we have finished processing the requests, see if we succeeded or not, if we did we need to set the indexes in the vbps for any & new requests if we didn't we need to clean up any thing we built */if (reply_pkt->error_stat) { /* First remove any entries that we created and reset the session ids for previously existing entries */ for(vbp = ax_pkt->data.proc_data.vbl_str.vblist, count = 0; count < ax_pkt->data.proc_data.vbl_str.vbl_count; vbp++, count++) { if (vbp->vb_priv == 0) continue; idata = (ENVOY_AX_INDEX_DATA_T *)vbp->vb_priv; if (vbp->ax_flags & ENVOY_AX_FLAGS_CLEAN_INDEX) { tnode = TREE_Get(context->indexroot, vbp->vb_obj_id.component_list, vbp->vb_obj_id.num_components, &length); (void) TREE_Extract(tnode, (ptr_t *)&ihdr); for (idatap = &ihdr->data; *idatap; idatap = &(*idatap)->next) { if (*idatap == idata) { *idatap = idata->next; break; } } switch(ihdr->type) { case VT_OBJECT: Clean_Obj_ID(&idata->data.objid); break; case VT_STRING: SNMP_memory_free(&idata->data.string.buffer); break; } SNMP_memory_free(idata); } else idata->session_id = 0; } for(vbp = ax_pkt->data.proc_data.vbl_str.vblist, count = 0; count < ax_pkt->data.proc_data.vbl_str.vbl_count; vbp++, count++) { if (vbp->ax_flags & ENVOY_AX_FLAGS_CLEAN_LEAF) { tnode = TREE_Get(context->indexroot, vbp->vb_obj_id.component_list, vbp->vb_obj_id.num_components, &length); (void) TREE_Extract(tnode, (ptr_t *)&ihdr); TREE_Delete(&context->indexroot, tnode); SNMP_memory_free(ihdr); } } }else { if (any_flag) { /* update the index value in the vbp */ for(vbp = ax_pkt->data.proc_data.vbl_str.vblist, count = 0; count < ax_pkt->data.proc_data.vbl_str.vbl_count; vbp++, count++) { idata = (ENVOY_AX_INDEX_DATA_T *)vbp->vb_priv; switch(vbp->vb_data_flags_n_type) { case VT_NUMBER: vbp->value_u.v_number = idata->data.bits32; break; case VT_STRING: EBufferClean(&vbp->value_u.v_string); EBufferPreLoad(BFL_IS_STATIC, &vbp->value_u.v_string, idata->data.string.buffer, idata->data.string.length); break; case VT_OBJECT: Clean_Obj_ID(&vbp->value_u.v_object); copy_object_id(&vbp->ax_search_end, &vbp->value_u.v_object); init_object_id(&vbp->ax_search_end); break; case VT_IPADDRESS: MEMCPY(&vbp->value_u.v_network_address, &idata->data.ipaddr, 4); break; } } } }return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -