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

📄 rsvp_path.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
📖 第 1 页 / 共 3 页
字号:
	Session		*destp;	PSB		*psbp;	packet_area	data;		/* Packet area */	struct packet	*new_pkt;	SenderDesc	*sdp = SenderDesc_of(pkt);	/*      Added by Mohit	 *      Check that INTEGRITY was included if it is required.	 */        if (in_vif >= 0	    && (IF_FLAGS(IF_UNICAST(in_vif))&IF_FLAG_Intgrty)	    && pkt->pkt_map->rsvp_integrity == NULL)                	return PKT_ERR_INTEGRITY;	destp = locate_session(pkt->rsvp_sess);	if (destp == NULL) {		log_event(LOGEV_ignore, "PATH-TEAR",			pkt->pkt_map->rsvp_session, "// No dest\n");		return(0);	}	/*	Locate PSB for same:	 *	  [Multicast dest:] (session, sender, PHOP, in_if)	 *	  [Unicast dest:]   (session, sender, PHOP)	 */	psbp = session_multicast(destp->d_session)?	      locate_PSB(destp, sdp->rsvp_stempl, in_vif,pkt->pkt_map->rsvp_hop):	      locate_PSB(destp, sdp->rsvp_stempl, -1, pkt->pkt_map->rsvp_hop);	if (!psbp)		return(0);	if (pkt->pkt_ttl == 0) {		Incr_ifstats(psbp->ps_in_if, rsvpstat_path_ttl0_in);		return(0);	}	Incr_ifstats(psbp->ps_in_if, rsvpstat_msgs_in[RSVP_PATH_TEAR]);	/*	 * If the PSB to be killed has the route change notification flag	 * set, and it's a multicast session, send a route query with	 * notification flag cleared to remove this route from notification	 * list in the multicast routing daemon.	 */	if (session_multicast(destp->d_session) &&		BIT_TST(psbp->ps_rsrr_flags, PSBF_RSRR_NOTIFY))		unnotify_rsrr(psbp, destp);	new_pkt = new_packet_area(&data);	tear_PSB(destp, psbp, new_pkt, pkt->pkt_map->rsvp_UnkObjList);	return 0;}/* * path_refresh(): This routine is called upon refresh timeout, to *	send Path refresh for all PSBs. */intpath_refresh(Session *destp){	packet_area	data;		/* Packet area */	struct packet	*pkt;	PSB		*psbp;	/* 	Time out expired path state.  If it's all gone, return -1.	 */	if (cleanup_path_state(destp) < 0)		return(-1);	/*	Build packet struct, map vector, and packet buffer, and	 *	set up common part of Path msg in map.	 */	pkt = new_packet_area(&data);	pkt->pkt_map->rsvp_msgtype = RSVP_PATH;	common_path_header(destp, pkt);	/*	 * For PSB, send refresh.	 */	for (psbp= destp->d_PSB_list; psbp; psbp = psbp->ps_next) {		path_refresh_common(destp, psbp, pkt);	}	dump_ds(0);	/* record state but not too often... */	return (0);}/* * path_refresh_PSB: This routine is called when path state is created *	or modified, to do an immediate refresh for specified PSB. */intpath_refresh_PSB(Session *destp, PSB *psbp){	packet_area	data;		/* Packet area */	struct packet	*pkt;	/*	Build packet struct, map vector, and packet buffer, and	 *	set up common part of Path msg in map.	 */	pkt = new_packet_area(&data);	pkt->pkt_map->rsvp_msgtype = RSVP_PATH;	common_path_header(destp, pkt);	path_refresh_common(destp, psbp, pkt);	dump_ds(0);	/* record state but not too often... */	return (0);}/* *	This routine sends a path refresh for a particular sender, *	i.e., a PSB.  This routine may be entered by either the *	expiration of the path refresh timer or directly as the result *	of the (Path_)Refresh_Needed flag being turned on during the *	processing of a received Path message. */intpath_refresh_common(Session *destp, PSB *psbp, struct packet *pkt){	SenderDesc	*sdscp = SenderDesc_of(pkt);	int		vif;	/*	Compute the IP TTL for the Path message as one less than	 *	the TTL value from the sender.  However, if the result is	 *	zero, return without sending the Path message.	 */	if ((pkt->pkt_ttl = psbp->ps_ip_ttl - 1) <= 0) {		Incr_ifstats(psbp->ps_in_if, rsvpstat_path_ttl0_out);		return(0);	}		 /*	Create a sender descriptor containing the SENDER_TEMPLATE,	  *	SENDER_TSPEC, and POLICY_DATA objects, if present in the	  *	PSB, and pack it into the Path message being built.	  */	sdscp->rsvp_stempl = psbp->ps_templ;	sdscp->rsvp_stspec = psbp->ps_tspec;	/*	 *	Copy into Path msg map a pointer to list of unknown objects	 *	to be forwarded.	 */	pkt->pkt_map->rsvp_UnkObjList = psbp->ps_UnkObjList;		/*	Send a copy of the Path message to each interface OI in	 *	OutInterface_list.  Before sending each copy:	 *	1. Pass any ADSPEC and SENDER_TSPEC objects present in the PSB	 *	   to the traffic control call TC_Advertise.  Insert the	 *	   modified ADSPEC object that is returned into the Path	 *	   message.	 *	2. If the PSB has the E_Police flag on but interface OI is	 *	   incapable of policing, turn on the E_Police flag in the	 *	   message.	 *	3. Insert into the PHOP object the interface address and	 *	   the LIH for the interface.	 */	sdscp->rsvp_adspec = NULL;	for (vif= 0; vif < if_num; vif++) {		if (IsNumAPI(vif))			continue;		if (IF_DOWN(vif))			continue;		if (!bmp_tst(&(psbp->ps_outif_list), vif))			continue;#ifdef SCHEDULE		if (psbp->ps_adspec)			sdscp->rsvp_adspec =				TC_Advertise(vif, psbp->ps_adspec,					(int) psbp->ps_flags&PSBF_NonRSVP);#endif /* SCHEDULE */		if ((psbp->ps_flags&PSBF_E_Police)&&						if_vec[vif].if_up==0)			session_set_flags(pkt->rsvp_sess,				session_get_flags(pkt->rsvp_sess)				| SESSFLG_E_Police);		send_path_out_vif(vif, destp, STempl_of(sdscp), pkt);		if (sdscp->rsvp_adspec) {			free(sdscp->rsvp_adspec);			sdscp->rsvp_adspec = NULL;		}	}	return(0);}/* * locate_PSB() returns the PSB matching a (SESSION, SENDER_TEMPLATE) and *		possibly in_vif and/or PHOP address.  In_vif < 0 and NULL *		PHOP address are wildcards. * */PSB         *locate_PSB(Session *destp, SENDER_TEMPLATE *filtp, int in_vif, RSVP_HOP *phop){	PSB         *sp;	for (sp = destp->d_PSB_list; sp != NULL; sp = sp->ps_next) {		if (match_filter(filtp, sp->ps_templ)) {			if ( (in_vif < 0 || in_vif == sp->ps_in_if)			  && (phop == NULL ||				hop_addr_eq(phop,&sp->ps_phop)))					return sp;		}	}	return (NULL);}/* * make_PSB(): Add a PSB data structure to a session */PSB *make_PSB(Session *dst, RSVP_HOP *phop, SENDER_TEMPLATE *stemp){	PSB	*psbp, **spp, *tsp;	psbp = (PSB *) calloc(1, sizeof(PSB));	if (!psbp) {		Log_Mem_Full("New sender");		return(NULL);	}	psbp->ps_ttd = time_now;	psbp->ps_next = NULL;	bmp_rst(&(psbp->ps_outif_list));	psbp->ps_rsrr_flags = 0;	/*	 *  Insert PSB in list in ascending order by sender IP address	 *	within phop.	 */	for (spp = &dst->d_PSB_list; ; spp = &((*spp)->ps_next)){		if (!(*spp) || hop_addr_lt(phop,&(*spp)->ps_phop)) {			/* First sender for this PHOP: insert it here and			 * set 1stphop field to point to itself.			 */			psbp->ps_next = *spp;			*spp = psbp;			psbp->ps_1stphop = psbp;			return(psbp);		}		if (hop_addr_eq(phop,&(*spp)->ps_phop))			break;	}	/*	 *	PHOP address already in list.	 */	if (filterspec_lt(stemp,(*spp)->ps_templ)){		/*		 *  Special case: new sender is first (smallest) address		 */		psbp->ps_1stphop = psbp;	/* pt to itself */		for (tsp = *spp; tsp ; tsp = tsp->ps_next) {			if (!hop_addr_eq(phop,&tsp->ps_phop))				break;			tsp->ps_1stphop = psbp;		}	} else {		psbp->ps_1stphop = *spp;		assert((*spp)->ps_1stphop == *spp);		for (spp = &((*spp)->ps_next); *spp ; spp = &((*spp)->ps_next)){			if (hop_addr_lt(phop,&(*spp)->ps_phop)			 || filterspec_lt(stemp,(*spp)->ps_templ))				break;		}	}	psbp->ps_next = *spp;	*spp = psbp;	return (psbp);}/* * kill_PSB(): This routine frees a PSB data structure. *	Called from cleanup_path_state (when sender times out) or *	from accept_path_tear. *	It deletes any dependent reservation state, and if all path and *	reservation state is gone, it deletes the session and returns -1. */intkill_PSB(Session *destp, PSB *psbp) {	PSB	**spp, *sp, *fsp;	int	from_net;	assert(destp);	if (!psbp)		return(0);	/*	 * remove PSB from linked list	 */	for (spp = &destp->d_PSB_list; (*spp) != NULL;				 		spp = &((*spp)->ps_next)) {		if ((*spp)->ps_1stphop == (*spp))			fsp = *spp;		if ((*spp) == psbp)			break;	}	if (*spp != NULL)		*spp = psbp->ps_next;	/*	If this was first PSB per phop, recompute 1stphop pointers.	 */	if (fsp == psbp) {		for (sp = psbp->ps_next; sp; sp = sp->ps_next) {			if (sp->ps_1stphop != psbp)				break;			sp->ps_1stphop = psbp->ps_next;		}	}	delete_resv4PSB(destp, psbp);	/* Delete any dangling reservations */	clear_scope_union(destp);	/* Set to recompute scope union */	from_net = !IsHopAPI(&psbp->ps_phop);	free((char *) psbp->ps_templ);	if (psbp->ps_tspec)		free((char *) psbp->ps_tspec);	if (psbp->ps_adspec)		free((char *) psbp->ps_adspec);	if (psbp->ps_BSB_Qb)		free((char *) psbp->ps_BSB_Qb);	if (psbp->ps_resv_spec)		free(psbp->ps_resv_spec);	FQkill(&psbp->ps_UnkObjList);	free((char *) psbp);	/* delete the PSB block itself */	/* Send Path Event upcall to all matching apps, except local state*/	if (from_net)		api_PATH_EVENT_upcall(destp);	if (!destp->d_PSB_list && !destp->d_RSB_list) {		kill_session(destp);		return(-1);	}	return (0);}/*	Locate "forwarding" PSB for specified session, sender.  Forwarding *	PSB is the PSB that is *not* marked LocalyOnly.  Return addr of PSB *	or NULL if there is none. */PSB *Find_fPSB(Session *destp, SENDER_TEMPLATE *filtp){	PSB		*sp;	for (sp = destp->d_PSB_list; sp != NULL; sp = sp->ps_next){		if (match_filter(filtp, sp->ps_templ)) {			if (!(sp->ps_flags&PSBF_LocalOnly))				return(sp);		}	}	return(NULL);}/* * cleanup_path_state(): For given session, kill all expired path state. *		Return 1 if something was killed, -1 if entire session *		was killed, else 0. */intcleanup_path_state(Session *destp){	PSB		*psbp, *psbpx;	packet_area	data;		/* Packet area */	struct packet	*pkt = NULL;	int		rc, killed = 0;	/*

⌨️ 快捷键说明

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