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

📄 rsvp_api.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
📖 第 1 页 / 共 4 页
字号:
	}	/*	Rebuild old packet map to include only those filter	 *	specs that don't match new packet map.  If any filter	 *	specs remain, send old packet as ResvTear.	 */	oj = 0;	for (oi = 0; oi < o_pkt->rsvp_nflwd; oi++) {		FILTER_SPEC *o_filtp = filter_of(FlowDesc_of(o_pkt, oi));		for (nk = 0; nk < n_pkt->rsvp_nflwd; nk++) {			if (match_filter(o_filtp,					filter_of(FlowDesc_of(n_pkt, nk))))				break;		}		if (nk == n_pkt->rsvp_nflwd) {			/* No match, filter should be torn down.			 */			if (!Style_is_Shared(style))				spec_of(FlowDesc_of(o_pkt, oj)) =					spec_of(FlowDesc_of(o_pkt, oi));			filter_of(FlowDesc_of(o_pkt, oj++)) =					filter_of(FlowDesc_of(o_pkt, oi));		}	}	if (oj) {		o_pkt->rsvp_nflwd = oj;		rsvp_pkt_process(o_pkt, NULL, api_num);	}	api_free_packet(o_pkt);	return(0);}/* * api_prepare_resv(): Accepts an API request for a resv. and turns it *		into a standard RSVP Resv packet... as if it arrived *		from another router (except in host byte order). *		Returns -1 if error, else 0. */intapi_prepare_resv(rsvp_req *req, api_rec *recp, struct packet *pkt)	{	Object_header	*objp;	packet_map	*mapp = pkt->pkt_map;	int		 styleID,LIH;	net_addr	host;		memset((char *)pkt->pkt_data, 0, sizeof(common_header));	mapp->rsvp_msgtype = pkt->pkt_data->rsvp_type = RSVP_RESV;	objp = (Object_header *)(pkt->pkt_data + 1);	mapp->rsvp_session = (SESSION *) objp;	session_create(mapp->rsvp_session, &recp->api_dest, recp->api_protid,				 0, (recp->api_flags&RAPI_GPI_SESSION) );	objp = Next_Object(objp);	/*	XXX Should check dstport != 0 if protid = 6 or 17.	 */		/*	Reservation local address: apply default and then	 *	map into interface number, which is passed in LIH.	 */	net_addr_assign_api_addr(&host,&req->rq_host,0);	if (IsAddrAPI(&host))		host = Get_local_addr;	/* This assumes if's are subset of vif's XXX */	LIH = map_if_addr(&host);		/* (signals: from API) */	mapp->rsvp_hop = (RSVP_HOP *) objp;	hop_if_create(pkt->rsvp_nhop,&GET_IF(api_num),LIH);	objp = Next_Object(objp);	New_Object(mapp->rsvp_timev, TIME_VALUES, TIME_VALUES_CTYPE);	pkt->rsvp_R = api_refresh_t;	/*	If requested by application, send CONFIRM object.	 */	if (req->rq_flags & RAPI_REQ_CONFIRM) {		mapp->rsvp_confirm = (CONFIRM *) objp;		confirm_if_create(mapp->rsvp_confirm,&Get_local_interface);		objp = Next_Object(objp);	}	/*	Style:  Map RAPI style into option vector	 */	styleID = req->rq_style;	New_Object(mapp->rsvp_style, STYLE, STYLE_CTYPE);	if (styleID > RAPI_RSTYLE_MAX) {		log(LOG_ERR, 0, "API: bad styleid\n");		return(-1);	}        mapp->rsvp_style->style_word = 	Styleid_to_Optvec[styleID];	pkt->rsvp_nflwd = req->rq_nflwd;	api_get_flows(objp, req, pkt);	/* XXX test for error */	/*	Finish up common header.	 *	Note: no checksum for API packet (per byte-order field)	 */	pkt->pkt_data->rsvp_cksum = 0;	pkt->pkt_data->rsvp_verflags = RSVP_MAKE_VERFLAGS(RSVP_VERSION, 0);	pkt->pkt_data->rsvp_length = pkt->pkt_len = 				(char *)objp - (char *) pkt->pkt_data;	/*	 *	If client sent bad local addr, send error upcall and return 0.	 */	if (LIH < 0) {		rsvp_resv_err(RSVP_Err_API_ERROR, RAPI_ERR_BADRECV, 0, 				(FiltSpecStar *) -1, pkt);		return(0);	}	/*	 *	If client sent DstPort in the SESSION object of zero	 *	but SrcPort in a FILTER_SPEC is non-zero, send 	 *	"Conflicting Src Port" error upcall and return 0.	 */	if (session_get_port(pkt->rsvp_sess) == 0 && filter_of(FlowDesc_of(pkt,0))) {	    int i;	    for (i =0; i < pkt->rsvp_nflwd ; i++)		if (filterspec_port(filter_of(FlowDesc_of(pkt,i))) != 0) {			rsvp_resv_err(RSVP_Err_API_ERROR, RAPI_ERR_BADSPORT, 0, 				(FiltSpecStar *) -1, pkt);			return(0);		}	}	return(1);   /* OK */}/*	Parse flow descriptor list of reservation request from API, and *	build map entries. */intapi_get_flows(Object_header *objp, rsvp_req *req, struct packet *pkt) {	int	i;	API_Flowspec	*api_specp;	API_FilterSpec	*api_filtp;	FlowDesc	*flwdp;	api_filtp = (API_FilterSpec *) After_APIObj(req->rq_policy);	for (i = 0; i < pkt->rsvp_nflwd; i++) {		flwdp = FlowDesc_of(pkt, i);		api_specp = (API_Flowspec *) After_APIObj(api_filtp);		switch (api_specp->form) {		    case RAPI_FLOWSTYPE_Intserv:			/* Check Intserv version */			if ((api_specp->specbody_IS.spec_mh.ismh_version&				INTSERV_VERS_MASK) != INTSERV_VERSION0)				return -1; 			/* XXX */			New_VObject(flwdp->rsvp_specp, FLOWSPEC,				FLOWSPEC_Intserv0,				size_api2d(api_specp->len));			Move_spec_api2d(api_specp, flwdp->rsvp_specp);			break;		    case RAPI_EMPTY_OTYPE:			flwdp->rsvp_specp = NULL;			break;		    default:			return -1;	/* XXX Reason code */		}		if (api_filtp->form != RAPI_EMPTY_OTYPE) {			flwdp->rsvp_filtp = (FILTER_SPEC *) objp;			Move_filter_api2d(api_filtp, flwdp->rsvp_filtp, TRUE);			objp = Next_Object(objp);		}		else			flwdp->rsvp_filtp = NULL;		api_filtp = (API_FilterSpec *) After_APIObj(api_specp);	}	return(0);}/* * api_prepare_path(): Accepts an API request for a path and turns *	it into a standard RSVP Path packet... as if it arrived * 	from another router (except in host byte order). */intapi_prepare_path(	rsvp_req	*req,	int		 len,	api_rec		*recp,	struct packet	*pkt)	{	SenderDesc	*sdscp;	Object_header	*objp;	packet_map	*mapp = pkt->pkt_map;	API_FilterSpec	*api_filtp;	API_TSpec 	*api_tspecp;	API_Adspec	*api_adspecp;	int		LIH;	memset((char *)pkt->pkt_data, 0, sizeof(common_header));	mapp->rsvp_msgtype = pkt->pkt_data->rsvp_type = RSVP_PATH;	objp = (Object_header *)(pkt->pkt_data + 1);	mapp->rsvp_session = (SESSION *) objp;	session_create(mapp->rsvp_session, &recp->api_dest,		recp->api_protid, SESSFLG_E_Police,		recp->api_flags & RAPI_GPI_SESSION);	objp = Next_Object(objp);	/*	 * Push flags from map into packet itself, and set version	 */	pkt->pkt_data->rsvp_verflags = RSVP_MAKE_VERFLAGS(RSVP_VERSION,						mapp->rsvp_flags);	/*	 * Only one flowspec (Tspec) per request.	 *	(Should be enforced by the client library routine).	 */	if (req->rq_nflwd != 1) {		log(LOG_ERR, 0, "API: sender nflwd > 1\n");		return(-1);	}	pkt->rsvp_nflwd = 1;	sdscp = SenderDesc_of(pkt);	api_filtp = (API_FilterSpec *) After_APIObj(req->rq_policy);	api_tspecp = (API_TSpec *) After_APIObj(api_filtp);	api_adspecp = (API_Adspec *)  After_APIObj(api_tspecp);	if ((char *)api_adspecp == (char *)req + len) {		/* No Adspec included in request		 */		api_adspecp = NULL;	}	else if (After_APIObj(api_adspecp) != (char *)req + len) {		log(LOG_ERR, 0, "API: Req len err\n");		return(-1);	}	/*	If local address is INADDR_ANY, set default interface.	 *	Map sender local address into interface number and pass	 *	it in LIH.  But if *not* our interface, set LIH = -1	 */	LIH = path_set_laddr(api_filtp);	/* (signals: from API) */	mapp->rsvp_hop = (RSVP_HOP *) objp;	hop_if_create(pkt->rsvp_phop,&GET_IF(api_num),LIH);	objp = Next_Object(objp);	New_Object(mapp->rsvp_timev, TIME_VALUES, TIME_VALUES_CTYPE);	pkt->rsvp_R = api_refresh_t;	sdscp->rsvp_stempl = (SENDER_TEMPLATE *) objp;	Move_filter_api2d(api_filtp, sdscp->rsvp_stempl, FALSE);	objp = Next_Object(objp);	New_VObject(sdscp->rsvp_stspec, SENDER_TSPEC, SENDER_TSPEC_CTYPE,					size_api2d(api_tspecp->len));	Move_tspec_api2d(api_tspecp, sdscp->rsvp_stspec);	/*	If sender gave us initial adspec, put it into Path message.	 *	Otherwise, call Traffic Control interface to create minimal	 *	adspec, and put that into message.	 */	if (api_adspecp) {		New_VObject(sdscp->rsvp_adspec, ADSPEC, ADSPEC_INTSERV,					size_api2d(api_adspecp->len));		Move_adspec_api2d(api_adspecp, sdscp->rsvp_adspec);	}	else {		New_VObject(sdscp->rsvp_adspec, ADSPEC, ADSPEC_INTSERV,                                       		(DFLT_ADSPEC_LEN));		New_Adspec(sdscp->rsvp_adspec);	}							/*	Finish up common header.	 *	Note: no checksum for API packet (per byte order field)	 */	pkt->pkt_data->rsvp_cksum = 0;	pkt->pkt_data->rsvp_length = pkt->pkt_len = 				(char *)objp - (char *) pkt->pkt_data;	pkt->pkt_data->rsvp_snd_TTL = (req->rq_ttl)? req->rq_ttl+1:							RSVP_TTL_MAX;	/* If local sender address was bad, generate an error upcall	 *	and return 0 => free the packet buffer	 */	if (LIH < 0) {		rsvp_path_err(-1, RSVP_Err_API_ERROR, RAPI_ERR_BADSEND, pkt);		return(0);	}	/*	 *	If the DstPort in the SESSION object was zero	 *	but SrcPort in SENDER_TEMPLATE was non-zero, 	 *	upcall with "Conflicting Src Port" error and free packet.	 */	if (session_get_port(pkt->rsvp_sess) == 0 &&	    filterspec_port(STempl_of(SenderDesc_of(pkt))) != 0) {		rsvp_path_err(-1, RSVP_Err_API_ERROR, RAPI_ERR_BADSPORT, pkt);		return(0);	}	return(1);}/*	Process rapi_status request. */intapi_status(rsvp_req *req)	{	Session *destp;	api_rec	*apip;	int	 i;	net_addr dest;	net_addr_assign_api_addr(&dest,&req->rq_dest,1);        if (!IsAddrAPI(&dest)) {		/* Specific destination  --         	 * Find the dest (session) record		 */		destp = locate_api_session(req,0);        	if (!destp) {			destp = locate_api_session(req,1);        		if (!destp)				return(-1);		}		api_dest_status(destp, req);		return(0);	}	/*	Else status of all destinations for this user process	 */	for (i=0, apip= api_table; i < API_TABLE_SIZE; i++, apip++) {		if (apip->api_fd == 0)			break;		if (apip->api_pid != req->rq_pid)			break;		destp = locate_api_session(req,					 (apip->api_flags&RAPI_GPI_SESSION));        	if (destp)			api_dest_status(destp, req);	}	return(0);}intapi_dest_status(Session *dest, rsvp_req *req)	{#ifdef ISI_TEST	if (req->rq_flags & RAPI_STAT_PATH) {		api_PATH_EVENT_upcall1(dest, UPCALL_MODE_STAT, ALL_SID);							/*  ?? XXX */	}	if (req->rq_flags & RAPI_STAT_RESV) {	/*** Need to call api_RESV_EVENT_upcall for all RSBs		api_RESV_EVENT_upcall_stat(dest, rp);	 ***/	}#endif /* ISI_TEST */	return(0);}/* *  api_PATH_EVENT_upcall():  Notify local API clients of (remote) *	Path state. Also, if there is an active reservation request *	from API, refresh it immediately. */voidapi_PATH_EVENT_upcall(Session *destp)	{	api_PATH_EVENT_upcall1(destp, UPCALL_MODE_PATH, ALL_SID);}/* *	Special case of PATH EVENT upcall: new API session has just *	registered; deliver any pending path state to it immediately. * */voidapi_PATH_EVENT_init(Session *destp, int sid)	{	api_PATH_EVENT_upcall1(destp, UPCALL_MODE_IFANY, sid);}	voidapi_PATH_EVENT_upcall1(Session *destp, int mode, int sid)	{	char		*resp_buf;	rsvp_resp	*resp;	API_TSpec	*tspecp;	API_FilterSpec	*filtp;	API_Adspec	*adsp;	PSB		*sp;	int		 resp_len;	/*	Make first pass over PSBs to compute length of required	 *	response message, and then malloc a buffer of that length.	 */	resp_len = sizeof(rsvp_resp);	for (sp = destp->d_PSB_list; sp != NULL; sp = sp->ps_next) {		if (mode != UPCALL_MODE_STAT && IsHopAPI(&sp->ps_phop))			continue;		resp_len += sizeof(rapi_filter_t) + 		      	 		size_d2api(Object_Size(sp->ps_tspec));		if (sp->ps_adspec)			resp_len += size_d2api(Object_Size(sp->ps_adspec));	}	/*   If there were no matches and if mode calls for suppression	 *	of null responses, return now.	 */	if (resp_len == sizeof(rsvp_resp) && mode != UPCALL_MODE_PATH)		return;	if (!(resp_buf = malloc(resp_len))) {		Log_Mem_Full("API Resp");		return;	}	memset(resp = (rsvp_resp *)resp_buf, 0, resp_len);	resp->resp_type = (mode == UPCALL_MODE_STAT)? RAPI_PATH_STATUS: 						      RAPI_PATH_EVENT;	resp_session_assign(resp,destp->d_session);	/*	 *	Second pass over PSBs to insert sender tspecs and templates	 */

⌨️ 快捷键说明

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