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

📄 rsvp_path.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
📖 第 1 页 / 共 3 页
字号:
	 *	For each expired PSB, forward PTear message to all	 *	outgoing vifs and then kill PSB.	 */	for (psbp = destp->d_PSB_list; psbp; psbp = psbpx) {		psbpx = psbp->ps_next;		if (!LT(psbp->ps_ttd, time_now))			continue;		killed = 1;		Incr_ifstats(psbp->ps_in_if, rsvpstat_path_timeout);		if (!pkt)			pkt = new_packet_area(&data);		rc = tear_PSB(destp, psbp, pkt, NULL);		if (rc < 0)			return -1;	}	return(killed);}/* *	Delete a PSB: forward PTear message to all outgoing vifs and then kill  *	PSB.  Common code for accept_path_tear() and cleanup_path_state(). *	In the first case, specify list of unknown objects to be forwarded. */inttear_PSB(Session *destp, PSB *psbp, struct packet *pkt, Fobject *fobjp){	SenderDesc 	*newsdp;	int		vif;	/*	 *	Generate PathTear message	 */	pkt->pkt_map->rsvp_msgtype = RSVP_PATH_TEAR;	common_path_header(destp, pkt);	newsdp = SenderDesc_of(pkt);	newsdp->rsvp_stempl = psbp->ps_templ;	/* Omit Sender_Tspec and Adspec. */	pkt->pkt_map->rsvp_UnkObjList = fobjp;	/*	 *	Send PathTear message to each outgoing vif.	 */	if (psbp->ps_ip_ttl > 0) {		pkt->pkt_ttl = psbp->ps_ip_ttl - 1;		for (vif = 0; vif < if_num; vif++) {			if (IsNumAPI(vif))				continue;			if (IF_DOWN(vif))				continue;			if (bmp_tst(&(psbp->ps_outif_list), vif))				send_path_out_vif(vif, destp,					 STempl_of(newsdp), pkt);		}	}	return (kill_PSB(destp, psbp));}voidcommon_path_header(Session *destp, struct packet *pkt){	static RSVP_HOP hop;	packet_map *mapp = pkt->pkt_map;	mapp->rsvp_session = destp->d_session;	if(pkt->pkt_map->rsvp_msgtype != RSVP_PATH_TEAR) {		mapp->rsvp_timev = &destp->d_timevalp;	}	mapp->rsvp_hop = &hop;	pkt->rsvp_nflwd = 1;	/* Exactly one sender */	switch(Obj_CType(destp->d_session)) {		case ctype_SESSION_ipv4:		case ctype_SESSION_ipv4GPI:			Init_Object(&hop,RSVP_HOP,RSVP_HOP_ipv4);			break;#ifdef	USE_IPV6		case ctype_SESSION_ipv6:		case ctype_SESSION_ipv6GPI:			Init_Object(&hop,RSVP_HOP,RSVP_HOP_ipv6);			break;#endif	/* USE_IPV6 */		default:			Init_Object(&hop,NULL,NULL);			break;	}}voidsend_path_out_vif(	int		vif,	Session		*destp,	SENDER_TEMPLATE *sdscp,	struct packet	*pkt){	assert(pkt->pkt_order == BO_HOST);	/*	 * Previous-Hop address = addr of output interface.	 */	hop_if_assign(pkt->rsvp_phop,&GET_IF(vif),vif);	send_pkt_out_vif(vif, destp, sdscp, pkt);}/*   query_routing(): Initiate/perform route computation for sender. *		Return 1 if asynchronous, else 0. * *   If destination is multicast and mrouted is running (and raw I/O?? XXX) *   then send RSRR message to mrouted requesting route for (S,G) and *   return 1.  For unicast routing, do synchronous lookup, set output *   bitmap *bm, and return 0.  For the API in a (possibly multihomed) *   host, match S against our interfaces to generate *bm, and return 0. */static intquery_routing(Session *destp, PSB *psbp, int *in_vifp, bitmap *bmp, int note){	int i;	u_char	stype, ptype;	int mcast;	bmp_rst(bmp);#define	TYPE_V4(x) ((x == ctype_SESSION_ipv4) || (x == ctype_SESSION_ipv4GPI))#ifdef	USE_IPV6#define	TYPE_V6(x) ((x == ctype_SESSION_ipv6) || (x == ctype_SESSION_ipv6GPI))#endif	/* USE_IPV6 */	stype = Obj_CType(&(destp->d_session->sess_header));	if (TYPE_V4(stype)) {		NET_SET_ADDR_IPv4(&dst, destp->d_session->sess4_addr);	}#ifdef	USE_IPV6	else if (TYPE_V6(stype)) {		NET_SET_ADDR_IPv6(&dst, destp->d_session->sess6_addr);	}#endif	/* USE_IPV6 */	mcast = session_multicast(destp->d_session);	/* Multicast session */	if (mcast) {		ptype = Obj_CType(&(psbp->ps_templ->filt_header));		switch (ptype) {			case ctype_SENDER_TEMPLATE_ipv4:				NET_SET_ADDR_IPv4(&src, psbp->ps_templ->filt4_srcaddr);				break;			case ctype_SENDER_TEMPLATE_ipv4GPI:				NET_SET_ADDR_IPv4(&src, psbp->ps_templ->filtgpi4_srcaddr);				break;#ifdef	USE_IPV6			case ctype_SENDER_TEMPLATE_ipv6:			case ctype_SENDER_TEMPLATE_ipv6FL:				NET_SET_ADDR_IPv6(&src, psbp->ps_templ->filt6_srcaddr);				break;			case ctype_SENDER_TEMPLATE_ipv6GPI:				NET_SET_ADDR_IPv6(&src, psbp->ps_templ->filtgpi6_srcaddr);				break;#endif	/* USE_IPV6 */			default:				/* shouldn't be here */				log(LOG_ERR,errno,"No such type");				break;		}		srcp = &src;	}	else 		srcp = 0;	if (!mcast) {		/*		 *	Unicast case.		 */		if (session_if(destp->d_session) >= 0) {			/* Unicast Path message destined to one of my			 *	interfaces.	That's it...			 */			return(0);		}		if ((TYPE_V4(stype) && !NoUnicast) #ifdef	USE_IPV6			|| (TYPE_V6(stype) && !NoUnicast)#endif	/* USE_IPV6 */		) {			i = rsrr_route_query((void *)psbp, (void *)destp, 					srcp, &dst, note, in_vifp, bmp);			if (i == -1) {				log(LOG_ERR,errno,"Unicast route error");				return -1;			}			if (i > 0)  /* (In case asynchronous) */				return(i);			i = bmptoif(bmp);			if (i == -1) {				log(LOG_ERR,errno,"bmptoif failed");				return -1;			}				return(0);		}	}	else  if ((TYPE_V4(stype) && !NoV4Mroute)#ifdef	USE_IPV6			|| (TYPE_V6(stype) && !NoV6Mroute)#endif	/* USE_IPV6 */	) {		/*		 *	Multicast case: If there is an mrouted, send RSRR		 *	route query and return 1 (asynch) unless route 		 *	notification is enabled for this PSB and PSB state		 *	has not changed.		 */#ifdef HOST_ONLY		assert(0);#else		/*		 * If we only intend to remove this route from the route change		 * notification list in the multicast routing daemon		 */		if (!note)			return rsrr_route_query((void *)psbp, (void *)destp, 				srcp, &dst, note, in_vifp, bmp);		if ((!BIT_TST(psbp->ps_rsrr_flags, PSBF_RSRR_NOTIFY) ||			psbp->ps_flags & PSBF_Prefr_need)) {			i = rsrr_route_query((void *)psbp, (void *)destp, srcp, 				&dst, note, in_vifp, bmp);			if (i > 0)				return(i);	/* Is asynchronous */			if (i == -1) {				log(LOG_ERR,errno,"Multicast route failed");				return -1;			}			return 0;		}		else {			*bmp = psbp->ps_outif_list;			*in_vifp = psbp->ps_in_if;			return(0);		}#endif /* HOST_ONLY */	}	if (IsHopAPI(&psbp->ps_phop)) {		/* If sender is local API, s_originvif is outgoing interface;		 * set this as the only route.		 */		bmp_set(bmp, psbp->ps_originvif);		*in_vifp = psbp->ps_in_if;		return(0);	}    	/*   Else... assume we are a host with one interface.	 */	/* Peserve the actual interface if we know it; else assume interface 0.	 */	if (*in_vifp < 0)		*in_vifp = 0;	return(0);}/*	route_update(): Update state after route computation. *		May be called synchronously (called from *		path_refresh_common()) or asyncronously (called *		from rsrr_update()). */voidroute_update(Session *destp, PSB *psbp, int in_vif, bitmap new_routes){	extern char s[];	int	mcast = 0;	PSB	*fPSB = Find_fPSB(destp, psbp->ps_templ);	if (!IsHopAPI(&psbp->ps_phop))		/* If it's from the network, send it to API, too */		bmp_set(&new_routes, api_num);	/*  Count Path messages.  Note: Delayed until here	 *  because may not have known incoming interface until	 *  asynchronous return from RSRR told us.	 */	if (in_vif >= 0)		Incr_ifstats(in_vif, rsvpstat_msgs_in[RSVP_PATH]);	mcast = session_multicast(destp->d_session);	if (IsHopAPI(&(psbp->ps_phop))) {		/* If inc iface was unknown, assume routing result		 */		if (psbp->ps_in_if < 0)			psbp->ps_in_if = in_vif;		fPSB = psbp;	}	else if (mcast) {   /* Multicast routing */		/* If inc iface was unknown, assume routing result		 */		if (psbp->ps_in_if < 0)			psbp->ps_in_if = in_vif;		/* If this Path msg arrived on an interface different from		 * what routing says but *psbp was the forwarding PSB, then		 * route has changed; make *psbp local-only. 		 */		if (psbp->ps_in_if != in_vif && fPSB == psbp) {			psbp->ps_flags |= PSBF_LocalOnly;			bmp_rst(&(psbp->ps_outif_list));			fPSB = locate_PSB(destp, psbp->ps_templ, in_vif, NULL);		}		/* Else if Path msg arrived on correct routing interface but		 * this PSB is not forwarding PSB (it was local-only), swap		 * local-only designation with forwarding PSB.		 */		else if (psbp->ps_in_if == in_vif && fPSB != psbp) {			if (fPSB) {				psbp->ps_outif_list = fPSB->ps_outif_list;				bmp_rst(&(fPSB->ps_outif_list));				fPSB->ps_flags |= PSBF_LocalOnly;			}			fPSB = psbp;			psbp->ps_flags &= ~PSBF_LocalOnly; 		}	}	else {		/*	Unicast routing or no routing (end system)		 */		fPSB = psbp;	}	/* We know incoming interface and sender is not from API; if	 * pkt arrived with UDP encaps, mark incoming interface UDP.	 */	if (psbp->ps_flags & PSBF_UDP) {		start_UDP_encap(in_vif);		if_vec[IF_UNICAST(in_vif)].if_flags |= IF_FLAG_UseUDP;	}	/*	If outgoing links have changed for existing PSB, set timer	 *	to initiate local repair (=> path refresh).	 */	if (fPSB && !bmp_equ(&(fPSB->ps_outif_list), &new_routes)) {		if (!bmp_zero(&(fPSB->ps_outif_list))){			if (IsDebug(DEBUG_RSRR)) {	    			log(LOG_DEBUG, 0,					"Outgoing vifs changed from %s\n",					bm_expand(&(fPSB->ps_outif_list), s));			}			add_to_timer((char *) destp,					TIMEV_LocalRepair, LOCAL_REPAIR_W);		}		fPSB->ps_outif_list = new_routes;	}}/* * Called when a PSB is going to be deleted, and it this PSB belongs to a * multicast session, while this PSB has the PSBF_RSRR_NOTIFY bit set. */static voidunnotify_rsrr(PSB *psbp, Session *ses){	int in_if = 0;	bitmap bmp;	if (BIT_TST(psbp->ps_rsrr_flags, PSBF_RSRR_NOTIFY))		query_routing(ses, psbp, &in_if, &bmp, 0);	return;}

⌨️ 快捷键说明

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