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

📄 rsvp_resv.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
📖 第 1 页 / 共 4 页
字号:
				(Object_header *) pkt->pkt_map->rsvp_confirm);		NeworMod = 1;	}	if (!new_RSB) {		/*		 *	If active RSB is not new, check whether STYLE, FLOWSPEC,		 *	or SCOPE objects have changed; if so, copy changed		 *	object into RSB and turn on the NeworMod flag.		 */		if (rp->rs_style != style) {		        rp->rs_style = style;		        NeworMod = 1;		}		if (Compare_Flowspecs(specp, rp->rs_spec) != SPECS_EQL) {			/* If flowspec has changed, keep old one in case			 *	Admission Control fails, and pass new one			 *	to link layer.			 */        		rp->rs_oldspec = rp->rs_spec;       			rp->rs_spec = copy_spec(specp);			rc = LL_ModFlowspec(rp->rs_OIf, destp, rp);			if (rc != LLDAL_RC_LATER)	/* synchronous */				Complete_ModFlowspec(destp, rp, rc);			if (rc == LLDAL_RC_ERROR)				return(-1);			NeworMod = 1;		}		if ((pkt->pkt_map->rsvp_scope_list) &&	 	   !match_scope(rp->rs_scope, pkt->pkt_map->rsvp_scope_list)){			clear_scope_union(destp); /* Recompute scope union */			if (rp->rs_scope)				free(rp->rs_scope);			rp->rs_scope = 				copy_scope(pkt->pkt_map->rsvp_scope_list);			NeworMod = 1;		}	}	return(NeworMod);}intComplete_NewFlow(Session *destp, RSB *rp, int rc)	{	if (rc == LLDAL_RC_ERROR) {		/*		 *	Admission Control failed for new RSB.  Send		 *	error msg using side-effect variable rsvp_errno		 *	and delete RSB.		 */		rsvp_RSB_err(destp, rp, Get_Errcode(rsvp_errno), 				Get_Errval(rsvp_errno) /* , 0 XXX */);		kill_newRSB(destp, rp);		return(-1);	}	/* If resv state (may have) changed and not API,	 *	do RESV_EVENT upcall now.	 */	if (!IsHopAPI(&rp->rs_nhop))                api_RESV_EVENT_upcall(destp, rp);	return(0);}intComplete_ModFlowspec(Session *destp, RSB *rp, int rc)	{	if (rc == LLDAL_RC_ERROR) {		/*		 *	Admission Control failed for existing RSB.  Send		 *	error msg using side-effect variable rsvp_errno		 *	and restore previous flowspec.  Delete any		 *	confirmation object.		 */		rsvp_RSB_err(destp, rp, Get_Errcode(rsvp_errno), 				Get_Errval(rsvp_errno)				 /* , ERROR_SPECF_InPlace XXX */);		if (rp->rs_oldspec) {			free((char *) rp->rs_spec);			rp->rs_spec = rp->rs_oldspec;			rp->rs_oldspec = NULL;		}		if (rp->rs_confirm)			free(rp->rs_confirm);		rp->rs_confirm = NULL;		return(-1);	}	else if (rp->rs_oldspec) {		free((char *) rp->rs_oldspec);		rp->rs_oldspec = NULL;	}			/* If resv state (may have) changed and network reservation,	 *	do RESV_EVENT upcall now.	 */	if (!IsHopAPI(&rp->rs_nhop))                api_RESV_EVENT_upcall(destp, rp);	return(0);}intComplete_ModFilter(Session *destp, RSB *rp, int rc)	{	if (rc == LLDAL_RC_ERROR) {		rsvp_RSB_err(destp, rp, Get_Errcode(rsvp_errno), 				Get_Errval(rsvp_errno)				 /* , ERROR_SPECF_InPlace XXX */);		return(-1);	}	/* If resv state (may have) changed and not API,	 *	do RESV_EVENT upcall now.	 */	if (!IsHopAPI(&rp->rs_nhop))                api_RESV_EVENT_upcall(destp, rp);	return(0);}intComplete_DelFlow(Session *destp, RSB *rp, int rc)	{	/* If resv state (may have) changed and not from API,	 *	do RESV_EVENT upcall now.	 *  Mark as teardown by deleting flowspec.	 */	if (!IsHopAPI(&rp->rs_nhop)) {		free(rp->rs_spec);		rp->rs_spec = NULL;                api_RESV_EVENT_upcall(destp, rp);	}	return(0);}/* *  accept_resv_tear(): Process an incoming ResvTear message */intaccept_resv_tear(	int		in_if,	/* Alleged outgoing iface (IGNORED)  */	struct packet	*pkt)	{	Session		*destp;	PSB		*sp;	RSB		*rp;	FiltSpecStar	filtss;	packet_area	data;	struct packet	*outpkt;	int		out_vif;	style_t		style = Style(pkt);	int		Refresh_Needed;	int		m_size = (char *) &pkt->pkt_map->rsvp_list -					(char *) pkt->pkt_map;	int		i, j, nmatch, rc;	RSVP_HOP	*nhopp;	/*	The logical outgoing interface OI is taken from the LIH in	 *	the NHOP object.	 */	/* Changed by Mohit from 	 * out_vif = hop_lih(pkt->rsvp_nhop);         */	out_vif = IsHopAPI(pkt->rsvp_nhop) ? api_num : hop_lih(pkt->rsvp_nhop);	nhopp = pkt->pkt_map->rsvp_hop;	Incr_ifstats(out_vif, rsvpstat_msgs_in[RSVP_RESV_TEAR]);	/*	Check that INTEGRITY was included if it is required.	 */	if ((IF_FLAGS(out_vif)&IF_FLAG_Intgrty) && 			pkt->pkt_map->rsvp_integrity == NULL)		return PKT_ERR_INTEGRITY;	destp = locate_session(pkt->rsvp_sess);	if (!destp)		return(0);	/*      Check that styles match.  Send BAD_STYLE error if not,	 *	and ignore ResvTear message [THIS CASE NOT IN SPEC]	 */        if ((rp = destp->d_RSB_list) && (rp->rs_style != style)) {                rsvp_resv_err(RSVP_Err_BAD_STYLE, 0, 0,                                        (FiltSpecStar *) -1 /*all*/, pkt);                return(0);        }				/*	Process the flow descriptor list in the ResvTear message to	 *	tear down local reservation state in style-dependent manner.	 */	if (!Style_is_Shared(style)) {		/* FF */		filtss.fst_count = 1;		for (i = 0; i < pkt->rsvp_nflwd; i++) {			filtss.fst_filtp0 = filter_of(FlowDesc_of(pkt, i));			rp = locate_RSB(destp, nhopp, &filtss, style);			Refresh_Needed |= kill_RSB(destp, rp);		}	}	else {	/* WF or SE */		rp = locate_RSB(destp, nhopp, NULL, style);		if (!rp)			return(0);		/*		 *	Mark filter specs to be torn down		 */		for (i=0; i < pkt->rsvp_nflwd; i++) {	    	    for (j= 0; j < rp->rs_fcount; j++) {			if (match_filter( filter_of(FlowDesc_of(pkt, i)),							rp->rs_Filtp(j))) {				free(rp->rs_Filtp(j));				rp->rs_Filt_TTD(j) = 0;			}	  	    }		}		/*	Squeeze out marked filter spec entries.  If filters		 *	are all gone, delete RSB and update LL; else just		 *	update LL.		 */		coalesce_filtstar(rp->rs_filtstar);		if (rp->rs_fcount == 0)			Refresh_Needed |= kill_RSB(destp, rp);		else {			rc = LL_ModFilter(rp->rs_OIf, destp, rp);			if (rc != LLDAL_RC_LATER)				Complete_ModFilter(destp, rp, rc);			if (rc == LLDAL_RC_ERROR)				return(-1);		}	}	/*	Create ResvTear msg template.  Copy into map everything	 *	up to flow descriptor list.  Make a separate copy of the	 *	HOP object, since we will change it when we send Tear msg(s).	 */	outpkt = new_packet_area(&data);	memcpy((char*) outpkt->pkt_map, (char *) pkt->pkt_map, m_size);	outpkt->pkt_map->rsvp_hop = (RSVP_HOP *)					copy_object((Object_header *)nhopp);	outpkt->pkt_map->rsvp_UnkObjList = pkt->pkt_map->rsvp_UnkObjList;	outpkt->rsvp_scope = NULL;	outpkt->rsvp_nflwd = 0;	/*	Forward ResvTear messages to all PHOPs whose PSBs route	 *	to the RSB that has been deleted.  Include a particular	 *	sender only if there are no other RSBs that were merged	 *	with the deleted RSB.	 *	 *      Select each PSB whose OutInterface_list includes the	 *	outgoing interface OI (more strictly, that routes to NHOP).	 *	For distinct style, SENDER_TEMPLATE must also match a	 *	filter spec in the received ResvTear.	 *	 *	This logic assumes that PSBs are ordered by phop address.	 */	nmatch = 0;	for (sp = destp->d_PSB_list; sp != NULL; sp = sp->ps_next) {		if (IsHopAPI(&sp->ps_phop))			continue;		if (!IsRoutePSB2nhop(destp, sp, nhopp))			continue;		if (Style_is_Wildcard(style)) {			nmatch++;			resv_tear_PSB(destp, sp, Style(pkt), NULL, outpkt);		}		else {			for (j = 0; j < pkt->rsvp_nflwd; j++) {			    if (match_filter(sp->ps_templ,					filter_of(FlowDesc_of(pkt, j)))) {				nmatch++;				/*	Do PSB-specific processing to build				 *	flow descriptor list in outpkt, if				 *	appropriate.				 */				resv_tear_PSB(destp, sp, Style(pkt),				     filter_of(FlowDesc_of(pkt,j)), outpkt);			    }			}		}		/*      If the next PSB is for a different PHOP or the last		 *	PSB has been processed, forward any ResvTear message		 *	that has been built.		 */		if (sp->ps_next == NULL ||		     !hop_addr_eq(&sp->ps_next->ps_phop,&sp->ps_phop)) {			if (outpkt->rsvp_nflwd)				send_resv_out(sp, outpkt);			outpkt->rsvp_nflwd = 0;		}	}	/*	If any PSB's were found in the preceding step, and if the	 *	Resv_Refresh_Needed flag is now on, execute the RESV REFRESH	 *	sequence.  resv_tear_PSB has set bits for incoming	 *	interfaces to be refreshed.	 */	if (nmatch > 0 && (Refresh_Needed))		resv_refresh(destp, 0);		free(outpkt->pkt_map->rsvp_hop);	dump_ds(1);	/* Log state change */	return(0);}/*	Do PSB-specific processing to create Resv_Tear message: build flow *	descriptor list in outpkt. */voidresv_tear_PSB(	Session 	*destp,	PSB		*sp,	style_t		 style,	FILTER_SPEC	*filtp,			/* NULL for wildcard */	struct packet	*outpkt)	{	FlowDesc	*outflwdp;	PSB		*BSBp, *tsp;		/*	Delete last FLOWSPEC sent to this PSB, and blockade state.	 */	tsp = (Style_is_Wildcard(style))? sp->ps_1stphop: sp;	if (tsp->ps_resv_spec) {		free(tsp->ps_resv_spec);		tsp->ps_resv_spec = NULL;	}	BSBp = tsp;	if (BSBp->ps_BSB_Qb) {		free(BSBp->ps_BSB_Qb);		BSBp->ps_BSB_Qb = NULL;		BSBp->ps_BSB_Tb = 0;	}	/* -    Search for an RSB (for any outgoing interface) to which the	 *	PSB routes and whose FILTER_SPEC matches the PSB.	 *	 * -	If an RSB is found, set to send a Resv refresh message to	 *	it, and return.	 */	if (RSB_match_path(destp, sp)) {		bmp_set(&(destp->d_r_incifs), sp->ps_in_if);		return;	}	/* -	Otherwise, add filter spec to the new ResvTear message	 *	being built.  We omit flowspec, as the protocol spec allows.	 */	outflwdp = FlowDesc_of(outpkt, outpkt->rsvp_nflwd);	outflwdp->rsvp_specp = NULL;	if (!Style_is_Wildcard(style) || outpkt->rsvp_nflwd == 0) {		outflwdp->rsvp_filtp = filtp;		outpkt->rsvp_nflwd++;	}}/* *	Resv refresh timeout has occurred.  Refresh all Resv state for *	given session. */		intresv_refresh_TimeOut(Session *destp)	{	PSB *sp;	/*	Clear last_FLOWSPEC pointers in all PSBs, and then	 *	call common routine resv_refresh().	 */	for (sp = destp->d_PSB_list; sp != NULL; sp = sp->ps_next) {		if (sp->ps_resv_spec)			free(sp->ps_resv_spec);		sp->ps_resv_spec = NULL;	}	return resv_refresh(destp, 0);}		/* * resv_refresh():  Sends refresh Resv refresh message(s). * *	Spec says resv refreshes are to be sent to specific PHOPs, or *	to all PHOPs.  This implementation cuts a corner, by sending *	resv refreshes to specific incoming interfaces, selected by  *	bits in d_r_incifs; no bits => all. * *	Parameter IsResvErr is 1 if entered from processing ResvErr. * *	Returns: 0 if timer should be rescheduled, else -1. */intresv_refresh(Session *destp, int IsResvErr)	{	struct packet	*pkt;	packet_area	 data;	PSB		*sp;	RSB		*rp;	style_t		 style;	/* Time out any expired state for this Session, and if it's	 *	all gone, return -1 => cancel refresh timer.	 */	cleanup_resv_state(destp);	/*	Create an output message containing INTEGRITY,	 *	SESSION, RSVP_HOP, and TIME_VALUES objects.	 */	pkt = new_packet_area(&data);	common_resv_header(pkt, destp);	/*	 *	Determine style for these reservations from the first	 *	RSB for the session, and move the STYLE object into	 *	the proto-message.	 */	rp = destp->d_RSB_list;	if (!rp)		return(-1);	style = rp->rs_style;	pkt->pkt_map->rsvp_style = &Style_Obj;	Init_Object(&Style_Obj,STYLE,STYLE_CTYPE);	Style_of(pkt)->style_word = style;	/*	If style is wildcard, form union of SCOPE lists from RSB's,	 *	with local senders deleted.  Call this scope_union.	 */	if (Style_is_Wildcard(style))		form_scope_union(destp);	/*	Initialize globals.  Then select each sender PSB for desired	 *	incinf and call resv_refresh_PSB() to add its contribution	 *	to merged (& packed) Resv refresh message.  For last PSB	 *	for same PHOP, resv_refresh_PSB sends resulting Resv.	 */	pkt->rsvp_nflwd = 0;	max_specp = NULL;	confRSBp = NULL;	UnkObjL_perPHOP = NULL;	for (sp = destp->d_PSB_list; sp != NULL; sp = sp->ps_next) {		/*		 * Ignore senders whose incoming interfaces are not needed now.		 */		if (!bmp_zero(&(destp->d_r_incifs))&&				!bmp_tst(&(destp->d_r_incifs), sp->ps_in_if))			continue;		resv_refresh_PSB(destp, sp, pkt, IsResvErr);	}	pkt->rsvp_nflwd = 0;	bmp_rst(&(destp->d_r_incifs));	if (confRSBp) {		free(confRSBp->rs_confirm);		confRSBp->rs_confirm = NULL;	}	return(0);}/* *	resv_refresh_PSB():  Process one PSB to generate Resv refresh *		message for its PHOP.  If this is last PSB for PHOP, *		send the Resv message. */intresv_refresh_PSB(	Session		*destp,	PSB		*sp,	struct packet	*pkt,	int		IsResvErr)	{	RSB		*rp;	PSB		*BSBp;	FlowDesc	*flwdp;	FLOWSPEC	*fwd_specp;	style_t		 style = Style(pkt);	int		 B_Merge = 0;	int		 i, n_match, cmp;	packet_map	*mapp = pkt->pkt_map;	int		 Need_Scope = 0;	Fobject		*UnkObjectL;	BSBp = (Style_is_Wildcard(style))? sp->ps_1stphop: sp;	n_match = 0;	UnkObjectL = NULL;	/*	 *	1. Select all RSBs whose Filter_spec_lists match the	 *	   SENDER_TEMPLATE object and whose OI appears in the	 *	   OutInterface_list of the PSB	 *	   (i.e., to which the given PSB will route).	 */	for (rp = destp->d_RSB_list; rp != NULL; rp = rp->rs_next) {		if (!PSBmaps2RSB(destp, sp, rp))			continue;		/* 	If sender in PSB is API, then:		 *	(a) If RSB has a CONFIRM object, then create and send		 *	    a ResvConf message containing the object, delete it.		 *	(b) Continue with next RSB.		 */

⌨️ 快捷键说明

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