⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ax_sa.c

📁 wm PNE 3.3 source code, running at more than vxworks6.x version.
💻 C
📖 第 1 页 / 共 5 页
字号:
* Indicate whether to remove operations for only this session (0) or for all * sessions (1) for this connection specified by <cookie>.* \i <session_id>* Specify the session id.* \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_cleanup_sessions(), * envoy_ax_sa_state_create(), envoy_ax_sa_handler(), envoy_ax_sa_state_init(), * 'ENVOY_AX_SA_MIB_ROOT_NODE()'*/int  envoy_ax_sa_session_loss(ENVOY_AX_SA_SB_T *sasb,			   ptr_t             cookie,			   int               sflag,			   bits32_t          session_id){ENVOY_AX_PKT_T *ax_pkt, **ax_pktp, *set_pkt = 0;#if INSTALL_ENVOY_SNMP_LOCKif (ENVOY_SNMP_GET_WRITE_LOCK(sasb->list_lock)) {    BUG(BUG_ENVOY_LOCKING, BUG_CONTINUABLE, 0,	(BUG_OUT, "envoy_ax_sa_session_loss: list lock is broken", 0));    return(-1);    }#endif/* first we get rid of any gnb ops for this transport */ax_pktp = &sasb->gnb_list;while (*ax_pktp) {    if ((ENVOY_AX_COOKIE_CMP((*ax_pktp)->cookie, cookie)) &&	(sflag || ((*ax_pktp)->session_id == session_id))) {        ax_pkt = *ax_pktp;        *ax_pktp = ax_pkt->next;	ax_pkt->error(ax_pkt->cookie, ENVOY_AX_SESS_LOSS);	ax_pkt->error = 0;	SNMP_Free(ax_pkt->pktp);	envoy_ax_pkt_free(ax_pkt);        }    else        ax_pktp = &(*ax_pktp)->next;    }/* next do the sets */ax_pktp = &sasb->set_list;while (*ax_pktp) {    if ((ENVOY_AX_COOKIE_CMP((*ax_pktp)->cookie, cookie)) &&	(sflag || ((*ax_pktp)->session_id == session_id))) {        switch((*ax_pktp)->data.proc_data.cur_phase) {            case 0:	        /* We haven't started the tests yet, we just need to cleanup		   the packets and tell the user that we are done with the		   packet */	        ax_pkt = *ax_pktp;		*ax_pktp = ax_pkt->next;		ax_pkt->error(ax_pkt->cookie, ENVOY_AX_SESS_LOSS);		ax_pkt->error = 0;		SNMP_Free(ax_pkt->pktp);		envoy_ax_pkt_free(ax_pkt);		break;	    case VFLAG_TEST_STARTED:		  /* we've started the tests tag it as needing to be cleaned */		(*ax_pktp)->data.proc_data.next_phase =		  ENVOY_AX_NEXT_CLEANUP_START;		break;	    case VFLAG_TEST_DONE:		/* we already finished the tests, unhook the packet from the		   list, it will be cleaned later after we release the list		   lock */		set_pkt = *ax_pktp;		*ax_pktp = set_pkt->next;		break;	    	    case VFLAG_SET_STARTED:		/* we've started the sets tag it as needing to be undone */		(*ax_pktp)->data.proc_data.next_phase =		  ENVOY_AX_NEXT_UNDO_START;		break;	    case VFLAG_SET_DONE:		/* we've finished the sets, try to undo them */		set_pkt = *ax_pktp;		(*ax_pktp)->data.proc_data.cur_phase = VFLAG_UNDO_STARTED;		break;	       /* An undo is already in progress, the packet is already being		  cleaned up */	    case VFLAG_UNDO_STARTED:		break;	      }        }    else        ax_pktp = &(*ax_pktp)->next;    }ENVOY_SNMP_RELEASE_WRITE_LOCK(sasb->list_lock);if (set_pkt) {    if (set_pkt->data.proc_data.cur_phase == VFLAG_TEST_DONE) {        set_pkt->error(set_pkt->cookie, ENVOY_AX_SESS_LOSS);	set_pkt->error = 0;	SNMP_Free(set_pkt->pktp);	envoy_ax_pkt_free(set_pkt);        }    else {#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(set_pkt->pktp->continue_lock)) {	    BUG(BUG_ENVOY_LOCKING, BUG_FATAL, 0,		(BUG_OUT,		 "envoy_ax_sa_session_loss(): packet continue lock is broken",		 0));	    return(0);	    }#endif	envoy_ax_sa_undo_pdu(set_pkt->pktp);	return(0);        }    }#if (INSTALL_ENVOY_SNMP_SERIALIZE) (void) envoy_tm_set(&sasb->defer, 0);#endif /* (INSTALL_ENVOY_SNMP_SERIALIZE) */return(0);}/****************************************************************************NAME: envoy_ax_sa_replyPURPOSE: call the completion routine to send a packetPARAMETERS: SNMP_PKT_T     *	    ENVOY_AX_PKT_T *RETURNS: int 0 on success****************************************************************************/static int  envoy_ax_sa_reply(SNMP_PKT_T     *pktp,		    ENVOY_AX_PKT_T *ax_pkt){ax_pkt->type        = ENVOY_AX_RESPONSE;ax_pkt->error_stat  = (bits16_t)pktp->pdu.std_pdu.error_status & 0xFFFF;ax_pkt->error_index = (bits16_t)pktp->pdu.std_pdu.error_index & 0xFFFF;if (ax_pkt->error_stat == 0) {    ax_pkt->data.proc_data.vbl_str.vblist = pktp->pdu.std_pdu.std_vbl.vblist;    ax_pkt->data.proc_data.vbl_str.vbl_count =      pktp->pdu.std_pdu.std_vbl.vbl_count;    ax_pkt->data.proc_data.vbl_str.vblp = pktp->pdu.std_pdu.std_vbl.vblp;    } (void) ax_pkt->send(ax_pkt->cookie, ax_pkt, 0, envoy_ax_pkt_size(ax_pkt, 0));ax_pkt->data.proc_data.vbl_str.vblist    = 0;ax_pkt->data.proc_data.vbl_str.vbl_count = 0;ax_pkt->data.proc_data.vbl_str.vblp      = 0;return(0);}/****************************************************************************NAME: envoy_ax_sa_get_continuePURPOSE: Determine if all the gets associated with the packet	 have finished.  If they haven't we release the continue	 lock and return.  Otherwise we try to send back a reply	 and cleanup the packet.  Finally if we are in serialization	 mode we update the serial stats and try to start other	 requests.PARAMETERS: SNMP_PKT_T *  The decoded GET PDURETURNS: void****************************************************************************/static void  envoy_ax_sa_get_continue(SNMP_PKT_T *pktp){VB_T *vbp;int count;#if (INSTALL_ENVOY_SNMP_SERIALIZE)ENVOY_AX_SA_SB_T *sasb = pktp->ax_pkt->sasb;#endif /* (INSTALL_ENVOY_SNMP_SERIALIZE) */if (pktp->phase != VFLAG_GET_DONE) {    vbp = pktp->pdu.std_pdu.std_vbl.vblist;    count = pktp->pdu.std_pdu.std_vbl.vbl_count;    for(; count; count--, vbp++) {        if (!(vbp->vb_flags & VFLAG_GET_DONE)) {#if (INSTALL_ENVOY_CONTINUE_REENTRANT)	    ENVOY_SNMP_RELEASE_WRITE_LOCK(pktp->continue_lock);#endif	    return;	    }        }    }#if (INSTALL_ENVOY_CONTINUE_REENTRANT)ENVOY_SNMP_RELEASE_WRITE_LOCK(pktp->continue_lock);#endif/* send the reply */ (void) envoy_ax_sa_reply(pktp, pktp->ax_pkt);envoy_ax_pkt_free(pktp->ax_pkt);SNMP_Free(pktp);#if (INSTALL_ENVOY_SNMP_SERIALIZE)sasb->readers--; (void) envoy_tm_set(&sasb->defer, 0);#endif /* (INSTALL_ENVOY_SNMP_SERIALIZE) */return;}/****************************************************************************\NOMANUALNAME: envoy_ax_sa_get_pduPURPOSE: Find the requested objects, and try to start all the         routines associated with them.  We call envoy_ax_sa_continue	 at the end to see if all of the gets have already succeeded	 it will handled any response and cleanup that is required.PARAMETERS: SNMP_PKT_T *  The decoded GET PDURETURNS: void****************************************************************************/void  envoy_ax_sa_get_pdu(SNMP_PKT_T *pktp){VB_T *vbp, *vbplist;int   count, indx;INT_32_T *err_stat;/* We will be looking at the error status a lot so we get a local pointer   to it to make things easier */err_stat = &(pktp->pdu.std_pdu.error_status);/* assume that everything will work */*err_stat = NO_ERROR;pktp->pdu.std_pdu.error_index = 0;pktp->cont = envoy_ax_sa_get_continue;vbplist = pktp->pdu.std_pdu.std_vbl.vblist;count = pktp->pdu.std_pdu.std_vbl.vbl_count;/* get some initial information */if ((vbplist == 0) || (count == 0)) {    pktp->phase = VFLAG_GET_DONE;    envoy_ax_sa_get_continue(pktp);    }/* Attempt to find all the requested objects, if we can't find an   object or it isn't readable we set it to a NO_SUCH_OBJECT exception,   tag the vbp as done and continue with the rest */for(indx = count, vbp = vbplist; indx; indx--, vbp++) {    if ((find_object_node(vbp, pktp, 0) != 0) ||        ((vbp->vb_ml.ml_flags & ML_IS_LEAF) == 0) ||        (((vbp->vb_ml.ml_leaf)->access_type & READ_ACCESS) == 0)) {        vbp->vb_data_flags_n_type = VT_NOSUCHOBJ;	vbp->vb_flags |= VFLAG_GET_STARTED | VFLAG_GET_DONE;        } /* if ((find_object...) */    } /* for(indx = 0...) *//* Now we loop through the vblist again and start all the gets.   If a get started flag is set then we either set it above or   the getproc of some other var bind has claimed responsibility for   it.  In either case we skip the var bind and continue.   We also test the error code after each call, if it is set we   skip all the remaining vbs and mark them as done so we won't   trip over them later.  We don't mark the vb that caused the   failure. */for(indx = count, vbp = vbplist; indx; indx--, vbp++) {    if (vbp->vb_flags & (VFLAG_GET_STARTED | VFLAG_GET_DONE))        continue;          ((vbp->vb_ml.ml_leaf)->getproc)      (vbp->vb_ml.ml_last_match, vbp->vb_ml.ml_remaining_objid.num_components,       vbp->vb_ml.ml_remaining_objid.component_list, pktp, vbp);    vbp->vb_flags |= VFLAG_GET_STARTED;    if (*err_stat) {        for (vbp++, indx--; indx; indx--, vbp++)            if (!(vbp->vb_flags & VFLAG_GET_STARTED))                vbp->vb_flags |= VFLAG_GET_STARTED | VFLAG_GET_DONE;        break;        }    }envoy_ax_sa_get_continue(pktp);}/****************************************************************************NAME: envoy_ax_sa_next_redoPURPOSE: Continuation of next/bulk processing.  This routine is	 responsible for looking over the varbind list and,	 for varbinds that have no such instance exceptions	 (indicating that we performed a get on them - due	 to the include bit) starting a nextproc, for varbinds	 that have the redo flag set we need to find the next	 object and try its nextproc.PARAMETERS: SNMP_PKT_T * the partially processed next/bulk pduRETURNS:  int    0 this stage of processing is finished continue onward.		-1 error, we also set the phase word to next_done                 1 Several nextprocs were restarted we need to redo this                   stage****************************************************************************/static int  envoy_ax_sa_next_redo(SNMP_PKT_T *pktp){VBL_T *vblp;VB_T *vbp, *tvbp, *oldvbp, *orgvbp;int count, indx;OBJ_ID_T target;int restart_flag = 0, temp_restart_flag;/* Get some initial information.  We need to determine which var bind list   to use.  Nexts have only one but bulks may have several chained together.   We want the last one as it will be the only one with variables that may   need to be redone.  We also get a pointer to the object list as the   base for this round.  We will need this pointer in the case of a v2   end of mib exception as we are suppossed to send back the object we   attempted a next from. */vblp = &(pktp->pdu.std_pdu.std_vbl);if (vblp->vblp == 0)    oldvbp = pktp->pdu.std_pdu.saved_vbl.vblist;else    for(oldvbp = vblp->vblist + pktp->pdu.std_pdu.non_reps, vblp = vblp->vblp;        vblp->vblp;        oldvbp = vblp->vblist, vblp = vblp->vblp)        ;if (((vbp = vblp->vblist) == 0) || ((count = vblp->vbl_count) == 0))    return(0);/* get a pointer to the section of the original vbp list   so we can check on the end of search range */if (vblp == &(pktp->pdu.std_pdu.std_vbl))    orgvbp = pktp->pdu.std_pdu.saved_vbl.vblist;else    orgvbp = pktp->pdu.std_pdu.saved_vbl.vblist + pktp->pdu.std_pdu.non_reps;/* loop through the varbind list figuring out which varbinds we   need to redo.  varbinds that have a no such instance exception   are gets (from the include bit) that failed, we reset the   started and done bits and use the nextproc from the current mib leaf.   varbinds that have a redo flag set are more complicated.  we need   to find the next object for them as well as resetting the flags.   lastly we need to check that any varbinds that have completed or   new objects we just found are within the search range.  any that   are out of range are cleaned and tagged with an end of mib indicator. */for(tvbp = vbp, indx = 0; indx < count; tvbp++, indx++, orgvbp++) {    if (tvbp->vb_data_flags_n_type == VT_NOSUCHINS) {        restart_flag = 1;	tvbp->vb_flags &= ~(VFLAG_NEXT_FLAGS | VFLAG_GET_DONE);	tvbp->vb_data_flags_n_type = VT_EMPTY;	continue;        }    temp_restart_flag = 0;    if (tvbp->vb_flags & VFLAG_NEXT_REDO) {        /* Redo is required, next proc was unable to find anything, go	   to next obj.  Chop off any instance qualifier and increment	   the last subid of the object id */	target.num_components = tvbp->vb_obj_id.num_components -	                        tvbp->vb_ml.ml_remaining_objid.num_components;	target.component_list = tvbp->vb_obj_id.component_list;	target.component_list[target.num_components-1]++;	tvbp->vb_obj_id.component_list = 0;	tvbp->vb_obj_id.num_components = 0;	tvbp->vb_flags &= ~VFLAG_NEXT_FLAGS;	/* 0 indicates that we couldn't find a next object so we tag it	   as end of mib.	   1 indicates some sort of error when performing the lookup */	switch(find_next_object(tvbp, &target, pktp, 0)) {            case 0:	        if (clone_object_id((&(oldvbp + indx)->vb_obj_id),				    &tvbp->vb_obj_id)) {		    Clean_Obj_ID(&target);		    pktp->pdu.std_pdu.error_status = GEN_ERR;		    pktp->phase = VFLAG_NEXT_DONE;		    return(-1);		    }		tvbp->vb_data_flags_n_type = VT_ENDOFMIB;		tvbp->vb_flags |= VFLAG_NEXT_STARTED | VFLAG_NEXT_DONE;		break;	    case -1:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -