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

📄 rsvp_resv.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * @(#) $Id: rsvp_resv.c,v 1.1.1.1 2000/05/08 22:51:24 wenqing Exp $ *//************************ rsvp_resv.c  ******************************* *                                                                   * *      Routines to receive, process, and send Resv and ResvTear     * *		messages.                                            * *                                                                   * *                                                                   * *********************************************************************//****************************************************************************            RSVPD -- ReSerVation Protocol Daemon                USC Information Sciences Institute                Marina del Rey, California            Original Version: Shai Herzog, Nov. 1993.	    Current Version:  Steven Berson & Bob Braden, may 1996.  Copyright (c) 1998 by the University of Southern California  All rights reserved.  Permission to use, copy, modify, and distribute this software and its  documentation in source and binary forms for any purpose and without  fee is hereby granted, provided that both the above copyright notice  and this permission notice appear in all copies, and that any  documentation, advertising materials, and other materials related to  such distribution and use acknowledge that the software was developed  in part by the University of Southern California, Information  Sciences Institute.  The name of the University may not be used to  endorse or promote products derived from this software without  specific prior written permission.  THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no representations about  the suitability of this software for any purpose.  THIS SOFTWARE IS  PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,  INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  Other copyrights might apply to parts of this software and are so  noted when applicable.********************************************************************/#include "rsvp_daemon.h"/*  Define some global objects * */STYLE		Style_Obj;CONFIRM		Confirm_Obj;/*	The following globals are used in merging reservations across *	different PSB's for the same PHOP. */static FLOWSPEC	*max_specp;static RSB	*confRSBp;static Fobject	*UnkObjL_perPHOP;/* External declarations */Session 	*locate_session(SESSION *);Session 	*locate_session_p(SESSION *);struct packet	*new_packet_area(packet_area *);int		match_filter(FILTER_SPEC *, FILTER_SPEC *);int		Compare_Flowspecs(FLOWSPEC *, FLOWSPEC *);FLOWSPEC	*LUB_of_Flowspecs(FLOWSPEC *, FLOWSPEC *);FLOWSPEC	*GLB_of_Flowspecs(FLOWSPEC *, FLOWSPEC *);int 		addTspec2sum(SENDER_TSPEC *, SENDER_TSPEC *);int		Compare_Tspecs(SENDER_TSPEC *, SENDER_TSPEC *);u_int32_t	Compute_R(TIME_VALUES *), Compute_TTD(TIME_VALUES *);int		match_scope(SCOPE *, SCOPE *);int		form_scope_union(Session *);void		scope_catf(SCOPE **, FILTER_SPEC *);void	 	rsvp_resv_err(int, int, int, FiltSpecStar *, struct packet *);void		rsvp_RSB_err(Session *, RSB *, int, int);Object_header	*copy_object(Object_header *);void		api_RESV_EVENT_upcall(Session *, RSB *);int		send_pkt_out_if(int, RSVP_HOP *, struct packet *);void		send_confirm(Session *, RSB *);void		clear_scope_union(Session *);char		*fmt_flowspec(FLOWSPEC *);char		*fmt_tspec(SENDER_TSPEC *);char		*cnv_flags(char *, u_char);void		FQkill(Fobject **);void		merge_UnkObjL2(Fobject **, Fobject **, int);int		match_policy(POLICY_DATA *, POLICY_DATA *);/* Link-layer Call-back routines. *	These core-RSVP routines perform processing that must *	follow completion of a corresponding LLDAL call. *	This is because LLDAL calls may invoke link-layer control *	functions that will not complete immediately, and avoids *	internal threading of rsvpd.  When an LLDAL call is *	asynchronous, it will return an immediate code indicating *	that, and then the LLDAL will invoke the call-back routine *	with the real return code when the function does complete. */int		Complete_NewFlow(Session *, RSB *, int);int		Complete_ModFlowspec(Session *, RSB *, int);int		Complete_ModFilter(Session *, RSB *, int);int		Complete_DelFlow(Session *, RSB *, int);/* Forward declarations */int		accept_resv(int, struct packet *);int		accept_resv_tear(int, struct packet *);int		flow_reservation(Session *, struct packet *, int,			FLOWSPEC *, FiltSpecStar *);void		resv_tear_PSB(Session *, PSB *, style_t, FILTER_SPEC *,							struct packet *);void		delete_resv4PSB(Session *, PSB *);static void	send_resv_out(PSB *, struct packet *);void		common_resv_header(struct packet *, Session *);void		common_resv_tear_header(struct packet *, Session *);RSB	*	make_RSB(Session *, int count);int		enlarge_RSB_filtstar(RSB *);RSB	*	locate_RSB(Session *, RSVP_HOP *, FiltSpecStar *, style_t);RSB	*	RSB_match_path(Session *, PSB *);int		kill_RSB(Session *, RSB *);void		kill_newRSB(Session *, RSB *);int		kill_RSB1(Session *, RSB *, int);void		resv_update_ttd(RSB *, u_int32_t);int		resv_refresh(Session *, int);int		resv_refresh_TimeOut(Session *);int		resv_refresh_PSB(Session *, PSB *, struct packet *, int);void		PSB_update_LL(Session *, PSB *);FiltSpecStar *	Get_FiltSpecStar(int);int		find_fstar(FILTER_SPEC *, FiltSpecStar *);int		match_filt2star(FILTER_SPEC *, FiltSpecStar *);int		set_need_scope(Session *);int		Styles_are_compat(style_t, style_t);int		IsRoutePSB2nhop(Session *, PSB *, RSVP_HOP *);int		is_scope_needed(Session *, PSB *);void		process_dummy_rtear(struct packet *);void		coalesce_filtstar(FiltSpecStar *);int		sameas_last_spec(FLOWSPEC **, FLOWSPEC *);void		process_dummy_rtear(struct packet *pkt);void		map2FiltStar(struct packet *, FiltSpecStar *);/* *		Common routines used by link-layer adaptation modules */int		Is_B_Police(Session *, RSB *);int		Compute_Path_Props(Session *, RSB *, FiltSpecStar *,					SENDER_TSPEC *, ADSPEC **, int *);#define PSBmaps2RSB(destp, sp, rp) \		 (IsRoutePSB2nhop(destp,sp,&rp->rs_rsvp_nhop) \			&& (Style_is_Wildcard(rp->rs_style) \			     || match_filt2star(sp->ps_templ, rp->rs_filtstar)))/* * accept_resv():  Process incoming Resv message, which is in host *	byte order.  It may be real packet from remote node or internal *	packet from local API. * *	pkt struct includes: *		pkt_data -> packet buffer *		pkt_map -> map of objects in packet *		pkt_ttl = TTL with which it arrived (if not UDP) *		pkt_flags & PKTFLG_USE_UDP: was it encapsulated? * *	This routine does the common checking and then calls *	flow_reservation() for each distinct flow descriptor packed *	into the message. *	 */intaccept_resv(	int		 vif,	    /* Phyint on which Resv msg arrived */	struct packet	*pkt)	{	int		 out_vif;	Session    	*destp;	int		 i, rc;	int		 need_refresh = 0;	style_t		 style;	FiltSpecStar	 filtss, *filtssp;	FLOWSPEC	*specp;	RSB		*rp;		assert(pkt->pkt_order == BO_HOST);	style = Style(pkt);	/* 	Determine Outgoing Interface OI.	 *	 * 	The logical outgoing interface OI is taken from the LIH in	 *	the NHOP object (non-RSVP cloud may cause packet to appear on 	 *	another interface).	 */	out_vif = IsHopAPI(pkt->rsvp_nhop) ? api_num : hop_lih(pkt->rsvp_nhop);	Incr_ifstats(out_vif, rsvpstat_msgs_in[RSVP_RESV]);	/*	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;			/*	Look for path state.  If it does not exist, send	 * 	"No path info" ResvErr msg.  If there is confusion about	 *	zero DstPorts, send "Conflicting Dest ports" error.	 */	destp = locate_session_p(pkt->rsvp_sess);	if (!destp) {		rsvp_resv_err(RSVP_Err_NO_PATH, 0, 0,					(FiltSpecStar *) -1 /*all*/, pkt);		return(-1);	}	else if ((int)destp == -1) {		rsvp_resv_err(RSVP_Err_BAD_DSTPORT, 0, 0,					(FiltSpecStar *) -1 /*all*/, pkt);		return(-1);	}	/*	 *   Check for incompatible styles, and if found, reject message	 *   with a "Conflicting style" error.	 *	Note: We use the strictest interpretation of conflicting	 *	styles: every RSB in a node must use the same style.	 *	Since the two directions of data flow through a node are	 *	independent and never their reservations are not merged,	 *	this is stronger than necessary.  But the less strict test 	 *	would require deciding which RSB's cannot be merged together,	 *	which would require nested loops over PSBs and RSBs.	 *		 */	for (rp = destp->d_RSB_list; rp != NULL; rp = rp->rs_next) {		if (!Styles_are_compat(rp->rs_style, style)) {			rsvp_resv_err(RSVP_Err_BAD_STYLE, 0, 0,					(FiltSpecStar *) -1 /*all*/, pkt);			return(-1);		}	}	/*	Process the flow descriptor list to make reservations,	 *	depending upon the style.  Filtss is a filter spec list.	 */	switch (style) {	    case STYLE_WF:		if (!pkt->rsvp_scope)			Incr_ifstats(out_vif, rsvpstat_no_inscope);		specp = spec_of(FlowDesc_of(pkt, 0));		rc = flow_reservation(destp, pkt, out_vif, specp, NULL);			break;	    case STYLE_FF:		/*	Style FF: execute independently for each flow		 *	descriptor in the message.		 */		rc = -1;		filtss.fst_count = 1;		for (i = 0; i < pkt->rsvp_nflwd; i++) {			int trc;			filtss.fst_Filtp(0) = filter_of(FlowDesc_of(pkt, i));			filtss.fst_Filt_TTD(0) = 0;			specp = spec_of(FlowDesc_of(pkt, i));			trc = flow_reservation(destp, pkt, out_vif, specp, 								&filtss);			rc = MAX(trc, rc);		}		break;	    case STYLE_SE:				/* Obtain storage and construct FILTER_SPEC*, i.e., 		 *	list of FILTER_SPECs, dynamically.		 */		filtssp = Get_FiltSpecStar(pkt->rsvp_nflwd);		if (!filtssp)	 		{			Log_Mem_Full("Resv1");			return(-1);		}		map2FiltStar(pkt, filtssp);		specp = spec_of(FlowDesc_of(pkt, 0));		rc = flow_reservation(destp, pkt, out_vif, specp, filtssp);		free(filtssp);					break;	    default:		rsvp_resv_err(RSVP_Err_UNKNOWN_STYLE, 0, 0,					(FiltSpecStar *) -1 /*all*/, pkt);		break;	}	if (rc < 0)		return(-1);	else if (rc > 0)		need_refresh = 1;	/*	 *	If any resv succeeded and refresh timer has not	 *	been started, start it now.	 */	if (destp->d_RSB_list && (Compute_R(&destp->d_timevalr) == 0))		add_to_timer((char *) destp, TIMEV_RESV, destp->d_Rtimor);	/*	If the refresh_needed flag is now on, execute	 *	resv_refresh to send immediate refresh through every	 *	interface noted in d_r_incifs.	 */	dump_ds(need_refresh);	if (need_refresh)		resv_refresh(destp, 0);	return(0);}/* * flow_reservation(): Process a given flow descriptor within a Resv *	msg, by finding or creating an RSB.  But if an error is found, *	create no RSB, send ResvErr message, and return. * *	Returns: -1 for error *	          1 OK, refresh needed *		  0 OK, no refresh */intflow_reservation(	Session		*destp,		/* Session			*/	Resv_pkt	*pkt,		/* Packet itself		*/	int		 out_vif,	/* True Outgoing interface	*/	FLOWSPEC	*specp,		/* Flowspec			*/	FiltSpecStar	*filtssp)	/* FILTER_SPEC* or NULL(WF)	*/	{	RSB		*rp;	PSB		*sp;	FILTER_SPEC	*filtp;	int		 NeworMod = 0;	int		 new_RSB = 0;	int		 sender_cnt, i, rc, nfilt;	u_int32_t	 time2die;	style_t		 style = Style(pkt);	nfilt = (Style_is_Wildcard(style))? 0 : filtssp->fst_count;			/*	Check the path state, as follows.	 *	 *	1. Locate the set of PSBs (senders) that route to OI and	 *	   whose SENDER_TEMPLATES match *filtssp.	 *	 *	   Count these PSBs, and add OI to a bit vector of	 *	   incoming interfaces for immediate refresh.	 */	sender_cnt = 0;	for (sp = destp->d_PSB_list ; sp != NULL; sp = sp->ps_next) {		if (!IsRoutePSB2nhop(destp, sp, pkt->pkt_map->rsvp_hop))			continue;		i = find_fstar(sp->ps_templ, filtssp);		if (i >= 0) {			if (!Style_is_Wildcard(style))				filtssp->fst_Filt_TTD(i) = 1;			sender_cnt++;			bmp_set(&(destp->d_r_incifs), sp->ps_in_if);		}	}	if (sender_cnt == 0) {		/*	If this set is empty, build and send an error message		 *	specifying "No Sender Information", and continue with		 *	the next flow descriptor in the Resv message.		 *		 * XXX We are using permissive interpretation for SE: OK		 *	if ANY of its FILTER_SPECs matches a sender.		 */ 		rsvp_resv_err(RSVP_Err_NO_SENDER, 0, 0, filtssp, pkt);		return(-1);	}	/*	Else delete from Filtss any FILTER_SPECs that match no PSB,	 */	else if (sender_cnt < nfilt)		coalesce_filtstar(filtssp);		/*	 *   o  Find or create a reservation state block (RSB) for	 *	(SESSION, NHOP).  If the style is distinct, Filtss is also	 *	used in the selection.  Call this the "active RSB".	 *		 *   o  Start or restart the cleanup timer on the active RSB, or,	 *	in the case of SE style, on each FILTER_SPEC of the RSB	 *	that also appears in Filtss.	 */	time2die = Compute_TTD(pkt->pkt_map->rsvp_timev);	rp = locate_RSB(destp, pkt->pkt_map->rsvp_hop, filtssp, style);	if (!rp) {		rp = make_RSB(destp, nfilt);		if (!rp) {			Log_Mem_Full("Resv3");			return(-1);		}		new_RSB = 1;		/*	Active RSB is new:		 *	1. Set NHOP, OI, and style from message.		 *	2. Copy FILTER_SPEC* into the RSB.		 *	3. Copy the FLOWSPEC and any SCOPE object into RSB.		 *	4. Set NeworMod flag on.	 	 */		rp->rs_nhop = *pkt->rsvp_nhop;		rp->rs_OIf = out_vif;		rp->rs_style = Style(pkt);		for (i = 0; i < nfilt; i++) {			filtp = copy_filter(filtssp->fst_Filtp(i));			if (!filtp && (filtssp->fst_Filtp(i))) {				kill_newRSB(destp, rp);				Log_Mem_Full("Resv5");				return(-1);			}			rp->rs_Filtp(i) = filtp;			rp->rs_Filt_TTD(i) = time2die;			rp->rs_fcount++;		}		rp->rs_spec = copy_spec(specp);		if (!rp->rs_spec) {			kill_newRSB(destp, rp);			Log_Mem_Full("Resv4");			return(-1);		}		if (pkt->pkt_map->rsvp_scope_list) {			rp->rs_scope= copy_scope(pkt->pkt_map->rsvp_scope_list);			if (!rp->rs_scope) {				kill_newRSB(destp, rp);				Log_Mem_Full("Resv6");				return(-1);			}		}		clear_scope_union(destp); /* Set to recompute scope union */		NeworMod = 1;		/*	Pass new flow to link layer		 */		rc = LL_NewFlow(rp->rs_OIf, destp, rp);		if (rc != LLDAL_RC_LATER)	/* synchronous */			Complete_NewFlow(destp, rp, rc);		if (rc == LLDAL_RC_ERROR)			return(-1);	}	/*	If the active RSB is not new, check whether Filtss from the	 *	message contains FILTER_SPECs that are not in the RSB; if	 *	so, add the new FILTER_SPECs and then invoke LL_ModFilter.	 *	Also update timeout on each filter.	 *	Note that we allow the order to change, requiring an N*N search.	 */	else {		int NewFilter = 0;		for (i= 0; i < nfilt; i++) {			FILTER_SPEC *nu_filtp = filtssp->fst_Filtp(i);			int	j;			j = find_fstar(nu_filtp, rp->rs_filtstar);			if (j < 0) {				j = find_fstar(NULL, rp->rs_filtstar);				if (j < 0) {					if (!enlarge_RSB_filtstar(rp)) {						Log_Mem_Full("Resv7");						return(-1);					}					j = find_fstar(NULL, rp->rs_filtstar);				}				rp->rs_Filtp(j) = copy_filter(nu_filtp);				NewFilter = 1;			}			rp->rs_Filt_TTD(j) = time2die;						}		if (NewFilter) {			NeworMod = 1;			rc = LL_ModFilter(rp->rs_OIf, destp, rp);			if (rc != LLDAL_RC_LATER)	/* synchronous */				Complete_ModFilter(destp, rp, rc);			if (rc == LLDAL_RC_ERROR)				return(-1);		}	}	/*	Free any old list of unknown objects, and save any new list.	 */	FQkill(&rp->rs_UnkObjList);	rp->rs_UnkObjList = pkt->pkt_map->rsvp_UnkObjList;	pkt->pkt_map->rsvp_UnkObjList = NULL;	resv_update_ttd(rp, time2die);	/*	 *	If the message contained a RESV_CONFIRM object, copy it	 *	into the RSB and turn on the NeworMod flag.	 */	if (pkt->pkt_map->rsvp_confirm) {		rp->rs_confirm = (CONFIRM *) copy_object(

⌨️ 快捷键说明

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