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

📄 rsvp_api.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * @(#) $Id: rsvp_api.c,v 1.1.1.1 2000/05/08 22:51:24 wenqing Exp $ *//************************ rsvp_api.c  ******************************** *                                                                   * *  Routines to handle application program interface of rsvpd        * *		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"#include "rsvp_api.h"#include "rapi_lib.h"#include <sys/uio.h> /* external declarations */int		refresh_api();void		rsvp_resv_err(int, int, int, FiltSpecStar *, struct packet *);void		rsvp_path_err(int, int, int, struct packet *);u_long		Styleid_to_Optvec[];int		writev();extern char	*style_names[];void		rapi_fmt_flowspec(rapi_flowspec_t *, char *, int);void		rapi_fmt_tspec(rapi_tspec_t *, char *, int);void		rapi_fmt_adspec(rapi_adspec_t *, char *, int);void		rapi_fmt_filtspec(rapi_filter_t *, char *, int);int		New_Adspec(ADSPEC *);Session *	locate_session(SESSION *);char	*	cnv_flags(char *, u_char);int		api_refresh_t;/* forward declarations */static void	send_to_api(int, rsvp_resp *, int);static void	print_api_request(rsvp_req *, int, int);void		api_PATH_EVENT_upcall(Session *);void		api_PATH_EVENT_init(Session *, int);void		api_PATH_EVENT_upcall1(Session *, int, int);void		api_RESV_EVENT_upcall(Session *, RSB *);void		api_RESV_EVENT_upcall_stat(Session *, RSB *);void		api_RESV_EVENT_upcall1(Session *, RSB *, int);void		api_PATH_ERR_upcall(struct packet *);void		api_RESV_ERR_upcall(struct packet *);static void	upcall_to_appl(rsvp_resp *, int, FILTER_SPEC *, int);static void	upcall_to_sid(rsvp_resp *, int, int);int		api_prepare_path(rsvp_req *, int, api_rec *, struct packet *);int		api_prepare_resv(rsvp_req *, api_rec *, struct packet *);int		api_new_packet(struct packet *, int, int);int		api_tear_oldresv(struct packet *, struct packet *);int		api_status(rsvp_req *);int		api_dest_status(Session *, rsvp_req *);int		api_get_flows(Object_header *, rsvp_req *, struct packet *);int		Move_spec_api2d(rapi_flowspec_t *, FLOWSPEC *);char *		Move_spec_d2api(FLOWSPEC *, rapi_flowspec_t *);int		Move_tspec_api2d(rapi_tspec_t *, SENDER_TSPEC *);char *		Move_tspec_d2api(SENDER_TSPEC *, rapi_tspec_t *);int		Move_adspec_api2d(rapi_adspec_t *, ADSPEC *);char *		Move_adspec_d2api(ADSPEC *, rapi_adspec_t *);int		Move_filter_api2d(rapi_filter_t *, FILTER_SPEC *, int);char *		Move_filter_d2api(FILTER_SPEC *, rapi_filter_t *);Session	*	locate_api_session(rsvp_req *, int);void		log_api_event(int, char *, net_addr *, int,				const char *, int, int);void		api_tear_path(api_rec *);void		api_tear_resv(api_rec *);void		api_free_packet(struct packet *);void		api_ERR_upcall_common(rsvp_resp *, struct packet *);int		path_set_laddr(rapi_filter_t *);void		hton_api_resp(rsvp_resp *, int);int		ntoh_rapi_flowspec(IS_specbody_t *);int		hton_rapi_flowspec(IS_specbody_t *);int		ntoh_rapi_adspec(IS_adsbody_t *);int		hton_rapi_adspec(IS_adsbody_t *);static int	resp_session_assign(rsvp_resp *resp, SESSION *session);int		net_addr_assign_api_addr(net_addr *addr,const api_addr *x,			int udp);/*	Macro used in api_prepare_xxxx to add an object to API packet and *	to the map of the packet.  The map address is 'var'; the object *	has class (typedef) 'cls' and ctype (value) 'ctype'. */#define New_Object(var, cls, ctype)  \	Init_Object(objp, cls, ctype); \	var = (cls *) objp; \	objp = Next_Object(objp);#define New_VObject(var, cls, ctype, len)  \	Init_Var_Obj(objp, cls, ctype,len); \	var = (cls *) objp; \	objp = Next_Object(objp);/* *	Array to translate style ID into option vector */u_long	Styleid_to_Optvec [] =	{/* 0 unused */ 0,	 /* 1 WF */     STYLE_WF,	 /* 2 FF */	STYLE_FF,	 /* 3 SE */	STYLE_SE	};/*	Define all-api-session value for session id parameter */#define ALL_SID -1/* * process_api_req(): Process request from API client, received over Unix *	socket.  Return -1 if API session should be closed. *	sid = my local handle. */intprocess_api_req(int sid, rsvp_req *req, int len)	{	api_rec		*recp = &api_table[sid];	common_header	*hdrp;	struct packet	new_pkt;	int		rc;	Session		*destp;		if (IsDebug(DEBUG_ALL)) {		print_api_request(req, len, sid);		if (l_debug >= LOG_HEXD && len > 0)			hexf(stderr, (char *) req, len);	}	if (len != 0 && (req->rq_version > VERSION_API		      || req->rq_version < VERSION_APImin)) {		log(LOG_ERR, 0, "API: bad version %d\n", req->rq_version);		return (-1);  /* Close it */	}	if (len == 0 || req->rq_type == API_CLOSE) {		/*		 * Close: Session close requested, or client terminated.		 * If there is stored Path (Resv) message, turn it into a		 * PathTear (ResvTear) message and procsss it as input.		 */		api_tear_path(recp);		api_tear_resv(recp);		return(-1);	/* Caller will delete session & timer */	}	switch (req->rq_type) {	case API2_REGISTER:		/*	REGISTER command handles 3 different functions:		 *	(1) Session registration (nflwd=0 & no Path state)		 *	(2) New Sender defn (nflwd=1)		 *	(3) Teardown sender (nflwd=0, path state exists)		 */		net_addr_assign_api_addr(&recp->api_dest,&req->rq_dest,1);		recp->api_protid =			(req->rq_protid)?req->rq_protid: RSVP_DFLT_PROTID;		if (req->rq_nflwd == 0) {			/*			 *	No sender descriptor => New registration			 *				or teardown request			 */			hdrp = recp->api_p_packet.pkt_data;			if (hdrp == NULL||hdrp->rsvp_type != RSVP_PATH) {				/*				 *  No path state exists => New session 				 *  registration.  If there is already path 				 *  state, trigger path event upcall.				 */				recp->api_flags = req->rq_flags & 					~(API_DIR_SEND|API_DIR_RECV|API_NET_BO);				if (NetByteOrderReq(req))					recp->api_flags |= API_NET_BO;				destp = locate_api_session(req,					     (recp->api_flags&RAPI_GPI_SESSION));				if (destp)					api_PATH_EVENT_init(destp, sid);								return(0);  /* None in place, just ignore */			}						/*			 * Turn path state into PathTear message, send it,			 * and then free API packet buffer & map.  If there			 * is no resv state either, stop refresh timer.			 */			recp->api_flags &= ~API_DIR_SEND;			api_tear_path(recp);			if (recp->api_r_packet.pkt_data == NULL)				del_from_timer((char *)					(unsigned long) sid, TIMEV_API);			return(0);		}		/* else, we are registering a sender.  Set up virtual Path		 * message.		 */		recp->api_flags |= API_DIR_SEND;		hdrp = recp->api_p_packet.pkt_data;		if (hdrp == NULL) {			/* 	Allocate space for a packet buffer.  (Use max			 *	message size; could compute actual size)  XXX			 */			if (api_new_packet(&recp->api_p_packet, 1, MAX_PKT) < 0)				return(-1);		}		rc = api_prepare_path(req, len, recp, &recp->api_p_packet);		if (rc == 0) {			/* There was a client error.  Delete packet.			 */			api_free_packet(&recp->api_p_packet);				return(0);		} else if (rc < 0) {			/* There was internal error.  Return -1 => caller			 *	will close the API socket.			 */			return(-1);		}		recp->api_p_packet.pkt_ttl =				recp->api_p_packet.pkt_data->rsvp_snd_TTL;		/*		 * We finished updating API state, now handle the request		 * itself		 */		refresh_api(sid);		break;	case API2_RESV:		/*	Reservation request.		 */		hdrp = recp->api_r_packet.pkt_data;		if (req->rq_nflwd == 0) {			recp->api_flags &= ~API_DIR_RECV;			/*			 *	No flow descriptors => teardown request			 */			if (hdrp == NULL||hdrp->rsvp_type != RSVP_RESV)				return(0);  /* None in place, just ignore */						/*	Send ResvTear and free Resv pkt buff and			 *	map.  If there is no path state either, stop			 *	refresh timer.			 */			api_tear_resv(recp);			if (recp->api_p_packet.pkt_data == NULL)				del_from_timer((char *)					(unsigned long) sid, TIMEV_API);			return(0);		}		/*	Initialize local packet struct with new data		 *	buffer and map, then call api_prepare_resv() to		 *	move request data into it.		 */		recp->api_flags |= API_DIR_RECV;		if (api_new_packet(&new_pkt, req->rq_nflwd, Max_rsvp_msg) < 0)			return(-1);		rc = api_prepare_resv(req, recp, &new_pkt);		if (rc == 0) {			/* There was a client error.  Delete packet.			 */			api_free_packet(&recp->api_r_packet);			return(0);		} else if (rc < 0) {			/* There was internal error.  Return -1 => caller			 *	will close the API socket.			 */			return(-1);		}		/*	If already have Resv, this is a modification;		 *	tear down state that is being removed, and then		 *	free old data buffer and map.		 */		if (hdrp) {			if (api_tear_oldresv(&recp->api_r_packet, &new_pkt)<0)				return(-1);		}		/*	Move pointers to data and map into API record		 */		recp->api_r_packet.pkt_data = new_pkt.pkt_data;			recp->api_r_packet.pkt_map = new_pkt.pkt_map;		recp->api_r_packet.pkt_len = new_pkt.pkt_len;		recp->api_r_packet.pkt_order = BO_HOST;		recp->api_r_packet.pkt_flags = 0;		recp->api_r_packet.pkt_ttl = 0;		/*		 * We finished updating API state; now handle the request		 * itself		 */		refresh_api(sid);		/*		 *	Delete any CONFIRM object, which is single-shot.		 */		recp->api_r_packet.pkt_map->rsvp_confirm = NULL;				break;	default:		log(LOG_ERR, 0, "API: Bad rq_type=%d\n", req->rq_type);		return (-1);	}	add_to_timer((char *) sid, TIMEV_API, api_refresh_t);		dump_ds(0);	return (0);}/* 	Allocate new packet buffer and new map for API. *	(Use max message size; could compute actual size)  XXX */intapi_new_packet(struct packet *pkt, int nflwd, int data_len)	{	common_header	*hdrp;	packet_map	*mapp;	int		 map_len = Map_Length(nflwd);	if ((hdrp = (common_header *) malloc(data_len))==NULL ||	    (mapp = (packet_map *) malloc(map_len))==NULL) {		Log_Mem_Full("API send/resv req");		return (-1);	}	pkt->pkt_offset = 0;	pkt->pkt_map = mapp;	pkt->pkt_data = hdrp;	pkt->pkt_len = 0;	pkt->pkt_flags = pkt->pkt_ttl = 0;	pkt->pkt_order = BO_HOST;	memset((char *)mapp, 0, sizeof(packet_map));	return(0);}voidapi_tear_path(api_rec *recp)	{	common_header	*hdrp = recp->api_p_packet.pkt_data;	if (!hdrp)		return;	hdrp->rsvp_type = RSVP_PATH_TEAR;	recp->api_p_packet.pkt_map->rsvp_msgtype = RSVP_PATH_TEAR;	rsvp_pkt_process(&recp->api_p_packet, NULL, api_num);	api_free_packet(&recp->api_p_packet);}voidapi_tear_resv(api_rec *recp)	{	common_header	*hdrp = recp->api_r_packet.pkt_data;			if (!hdrp)		return;	hdrp->rsvp_type = RSVP_RESV_TEAR;	recp->api_r_packet.pkt_map->rsvp_msgtype = RSVP_RESV_TEAR;	/*	 * Note that the RSVP spec is designed to allow us to make a valid	 * ResvTear msg from a Resv msg, by just changing the message type.	 * We could explicitly delete the flowspec from the ResvTear, but	 * it's better to exercise the logic that ignores the flowspec.	 */	rsvp_pkt_process(&recp->api_r_packet, NULL, api_num);	api_free_packet(&recp->api_r_packet);}voidapi_free_packet(struct packet *pkt)	{	if (pkt->pkt_data)		free(pkt->pkt_data);	if (pkt->pkt_map)		free(pkt->pkt_map);	pkt->pkt_data = NULL;	pkt->pkt_map = NULL;	pkt->pkt_len = 0;}/*	Tear down API state in o_pkt that does not appear in n_pkt. */intapi_tear_oldresv(struct packet *o_pkt, struct packet *n_pkt)	{	int		oi, oj, nk;	style_t		style = Style(o_pkt);	o_pkt->pkt_map->rsvp_msgtype = RSVP_RESV_TEAR;	if (style != Style(n_pkt)) {		/*	Styles differ.  Just tear down old Resv.		 */		rsvp_pkt_process(o_pkt, NULL, api_num);		api_free_packet(o_pkt);		return(0);

⌨️ 快捷键说明

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