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

📄 rsvp_path.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * @(#) $Id: rsvp_path.c,v 1.1.1.1 2000/05/08 22:51:24 wenqing Exp $ *//************************ rsvp_path.c  ******************************* *                                                                   * *  Routines to receive, process, and send Path and PathTear         * *		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) 1996 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"/* external declarations */Session		*make_session(SESSION *);Session		*locate_session(SESSION *);Session		*locate_session_p(SESSION *);int		start_UDP_encap();void		api_PATH_EVENT_upcall(Session *);int		send_pkt_out_vif(int, Session *, FILTER_SPEC *, struct packet *);void		move_object();int		Compare_Tspecs(SENDER_TSPEC *, SENDER_TSPEC *);Object_header 	*copy_object(Object_header *);struct packet 	*new_packet_area(packet_area *);ADSPEC		*TC_Advertise(int, ADSPEC *, int);int		match_filter(FILTER_SPEC *, FILTER_SPEC *);u_int32_t	Compute_TTD(TIME_VALUES *), Compute_R(TIME_VALUES *);char		*bm_expand();#ifndef HOST_ONLYvoid		rsrr_send_rq();#endifvoid		delete_resv4PSB();void		PSB_update_LL(Session *, PSB *);int		resv_refresh(Session *, int);void		clear_scope_union(Session *);Fobject		*FQrmv(Fobject **);void		FQkill(Fobject **);int		match_policy(POLICY_DATA *, POLICY_DATA *);/* forward declarations */int		accept_path(int, struct packet *);int		accept_path_tear(int, struct packet *);PSB		*locate_PSB(Session *, SENDER_TEMPLATE *, int, RSVP_HOP *);static PSB	*make_PSB(Session *, RSVP_HOP *, SENDER_TEMPLATE *);int		kill_PSB(Session *, PSB *);PSB *		Find_fPSB(Session *, SENDER_TEMPLATE *);void		finish_path(Session *, PSB *);void		multicast_path_tear(Session *, struct packet *);void		common_path_header(Session *, struct packet *);int		check_dstport_conflict(struct packet *);int		path_refresh_common(Session *, PSB *, struct packet *);int		path_refresh_PSB(Session *, PSB *);void		send_path_out_vif(int, Session *, SENDER_TEMPLATE *,							struct packet *);int		tear_PSB(Session *, PSB *, struct packet *, Fobject *);extern int rsrr_route_query(void*,void *,net_addr *,net_addr *,int,int *,bitmap *);extern int bmptoif(bitmap *);void	route_update(Session *, PSB *, int, bitmap);static int query_routing(Session *, PSB *, int *, bitmap *, int);static void unnotify_rsrr(PSB *, Session *);static net_addr src, dst;  static net_addr *srcp = &src;/* static net_addr *dstp = &dst; *//* * accept_path() This routine processes an incoming Path message, *	to build/refresh path state. * *	in_vif = incoming vif, or -1 if unknown (multicast UDP encap'd) */intaccept_path(int in_vif, struct packet *pkt){	u_int32_t	 ttd;	Session   	*destp;	PSB       	*psbp;	RSB		*rp;	bitmap		 new_routes;	int		 rr_vif = 0;	SenderDesc   	*sdp = SenderDesc_of(pkt);	FILTER_SPEC	*filtp;	Fobject		*fop;	int rv;	bmp_rst(&new_routes);        /*      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;                	/*	 * Find/build a Session block	 *	 *	    If (a PSB is found whose) session matches the     	 *	    DestAddress and Protocol Id fields of the received     	 *	    SESSION object, but the DstPorts differ and one is     	 *	    zero, then build and send a "Conflicting Dst Port"    	 *	    PathErr message, drop the Path message, and return.	 */	destp = locate_session_p(pkt->rsvp_sess);	if ((int)destp == -1) {		rsvp_path_err(in_vif, RSVP_Err_BAD_DSTPORT, 0, pkt);		return(-1);	}		else if (destp == NULL) {		destp = make_session(pkt->rsvp_sess);		if (!destp)			return(-1);	}        /*	Search for a path state block (PSB) whose (session,	 *	sender_template) pair matches the corresponding objects	 *	in the message.  For a multicast session, also match	 *	IncInterface; for a unicast session, match PHOP address. 	 */	psbp = IsHopAPI(pkt->rsvp_phop)?	           locate_PSB(destp, sdp->rsvp_stempl, -1, NULL) :		session_multicast(destp->d_session)?	           locate_PSB(destp, sdp->rsvp_stempl, in_vif, NULL) :		   locate_PSB(destp, sdp->rsvp_stempl, -1, 						pkt->pkt_map->rsvp_hop);	if (psbp == NULL) {		/*		 *	If there is no matching PSB, create a new PSB.		 */		psbp = make_PSB(destp, pkt->pkt_map->rsvp_hop, 							sdp->rsvp_stempl);		if (!psbp)			return(-1);		/*		 *	Copy contents of the SENDER_TEMPLATE, SENDER_TSPEC,		 *	and PHOP (IP address and LIH) objects into		 *	the PSB.		 */		psbp->ps_templ = copy_filter(sdp->rsvp_stempl);		psbp->ps_tspec = copy_tspec(sdp->rsvp_stspec);		Move_Object(pkt->pkt_map->rsvp_hop, &psbp->ps_rsvp_phop);		psbp->ps_Frpolicy = pkt->pkt_map->rsvp_dpolicy;		pkt->pkt_map->rsvp_dpolicy = NULL;		/*	If the sender is from the local API, set		 *	OutInterface_List to the single interface whose		 *	address matches the sender address, and make		 *	IncInterface undefined.  Otherwise, record iface		 *	on which it arrived, and for multicast, turn on		 *	Local_Only flag.		 */		if (IsHopAPI(pkt->rsvp_phop)) {			psbp->ps_in_if = api_num;			psbp->ps_originvif = (u_char) hop_lih(pkt->rsvp_phop);		} else {			psbp->ps_in_if = in_vif;			if (session_multicast(destp->d_session)) {				psbp->ps_flags |= PSBF_LocalOnly;			}		}		/*	If this is the first PSB for the session, start a		 *	refresh timer.		 */		if (Compute_R(&destp->d_timevalp) == 0)			add_to_timer((char *) destp, TIMEV_PATH, destp->d_Rtimop);		/*	Since new sender is added, must recompute scope union.		 */		clear_scope_union(destp);		/*	Turn on the Path_Refresh_Needed flag.  If there		 *	is WF path state, also send Resv refresh.		 */		psbp->ps_flags |= PSBF_Prefr_need;		if ((rp = destp->d_RSB_list) != NULL		  && Style_is_Wildcard(rp->rs_style))			psbp->ps_flags |= PSBF_Rrefr_need;				}	else {		/*	Otherwise (there is a matching PSB):		 *		 *	If a PSB is found with a matching sender host but the     		 *	SrcPorts differ and one of the SrcPorts is zero, then     		 *	build and send an "Conflicting Sender Port" PathErr 		 *	message, drop the Path message, and return.		 */		filtp = STempl_of(sdp);		if (!match_filter((FILTER_SPEC *)filtp, psbp->ps_templ)){			rsvp_path_err(in_vif, RSVP_Err_BAD_SNDPORT, 0, pkt);			return(-1);		}		/*	If the PHOP IP address or the LIH differs between the 		 *	message and the PSB, copy the new value into the PSB		 *	and turn on the Resv_Refresh_Needed flag.                 *	If the sender Tspec differs, copy the new value into		 *	the PSB and turn on the Path_Refresh_Needed flag.		 */		if (!IsHopAPI(&psbp->ps_phop) &&				!hop_eq(pkt->rsvp_phop,&psbp->ps_phop)) {			Move_Object(pkt->pkt_map->rsvp_hop, &psbp->ps_rsvp_phop);			psbp->ps_flags |= PSBF_Rrefr_need;		}							if (Compare_Tspecs(sdp->rsvp_stspec, psbp->ps_tspec) 								!= SPECS_EQL) {			free((char *) psbp->ps_tspec);			psbp->ps_tspec = copy_tspec(sdp->rsvp_stspec);			psbp->ps_flags |= PSBF_Prefr_need;		}	}	/*	Update the current PSB, as follows.	 *	 *	-  Start or restart the cleanup timer for the PSB.	 *	 *	-  Copy current Adspec into the PSB.	 *	 *	-  Copy E_Police flag from SESSION object into PSB.	 *	 *	-  Store the received TTL into the PSB.	 *	   If the received TTL differs from Send_TTL in the RSVP	 *	   common header, set the Non_RSVP flag on in the PSB.	 *	 *	-  Free any old unknown objects and save any new ones.	 *	 */	ttd = Compute_TTD(pkt->pkt_map->rsvp_timev);	if (LT(psbp->ps_ttd, ttd))  /* Update sender time-to-die */			psbp->ps_ttd = ttd;        if ((sdp->rsvp_adspec)) {                if (psbp->ps_adspec)			free((char *) psbp->ps_adspec);                psbp->ps_adspec = copy_adspec(sdp->rsvp_adspec);        }	if (session_get_flags(pkt->rsvp_sess) & SESSFLG_E_Police)		psbp->ps_flags |= PSBF_E_Police;	psbp->ps_ip_ttl = pkt->pkt_ttl; /* Set/update IP TTL */	if (pkt->pkt_ttl != pkt->pkt_data->rsvp_snd_TTL)		psbp->ps_flags |= PSBF_NonRSVP;	FQkill(&psbp->ps_UnkObjList);	psbp->ps_UnkObjList = pkt->pkt_map->rsvp_UnkObjList;	pkt->pkt_map->rsvp_UnkObjList = NULL;	/*	If policy objects have changed (or order has chnaged),	 *	free the old ones, save the new ones, and pass them	 *	to policy control.	 */	for (fop= pkt->pkt_map->rsvp_dpolicy; fop; fop = fop->Fobj_next){		if (!match_policy((POLICY_DATA *) &fop->Fobj_objhdr,				 (POLICY_DATA *) 					&psbp->ps_Frpolicy->Fobj_objhdr)){			FQkill(&psbp->ps_Frpolicy);			psbp->ps_Frpolicy = pkt->pkt_map->rsvp_dpolicy;			pkt->pkt_map->rsvp_dpolicy = NULL;			/* Call Policy Control */			break;		}	}	/*	 *	If packet arrived with UDP encapsulation, set flag bit.	 */	if (pkt->pkt_flags&PKTFLG_USE_UDP)		psbp->ps_flags |= PSBF_UDP;	/*	Perform/Initiate route computation.  Maybe it is	 *	asynchronous...  If not, update state now, using	 *	incoming interface and outgoing link info, then	 *	finish Path processing by doing any needed refreshes.	 */	rr_vif = in_vif;	rv = query_routing(destp,psbp,&rr_vif,&new_routes, 1);	if (rv == -1) {		log(LOG_ERR,0,"error in query_routing");		return -1;	}	if (!rv) {		/* synchronous reply */		route_update(destp, psbp, rr_vif, new_routes);		finish_path(destp, psbp);	}	return(0);}/*	Finish processing Path message after completion of perhaps *	asynchronous route query. */voidfinish_path(Session *destp, PSB *psbp){	dump_ds(psbp->ps_flags & PSBF_Prefr_need);		if (psbp->ps_flags&PSBF_Prefr_need) {		psbp->ps_flags &= ~PSBF_Prefr_need;		/*		 *   Path state is new or modified.		 *	1. If Path message came from a network interface,		 *	   make a Path Event upcall for each local		 *	   application for this session.		 *		 *	2. Generate immediate Path refresh for this PSB		 *		 *	3. Update traffic control to match (new?) path state.		 */ 		if (!IsHopAPI(&psbp->ps_phop))			api_PATH_EVENT_upcall(destp);		path_refresh_PSB(destp, psbp);		PSB_update_LL(destp, psbp);	}	/*	If needed, generate immediate Resv refreshes for this	 *	PSB.  Send Resv refresh towards all senders using same	 *	incoming interface (perhaps multiple PHOPs).	 */	if (psbp->ps_flags & PSBF_Rrefr_need) {		psbp->ps_flags &= ~PSBF_Rrefr_need;		bmp_set(&(destp->d_r_incifs), psbp->ps_in_if);		resv_refresh(destp, 0);	}}/* *  accept_path_tear(): Processes an incoming PathTear message. */intaccept_path_tear(int in_vif, struct packet *pkt){

⌨️ 快捷键说明

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