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

📄 rsvp_api.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
📖 第 1 页 / 共 4 页
字号:
	filtp = (API_FilterSpec *) resp->resp_flows;	for (sp = destp->d_PSB_list; sp != NULL; sp = sp->ps_next) {		if (mode != UPCALL_MODE_STAT && IsHopAPI(&sp->ps_phop))			continue;                tspecp = (API_TSpec *) Move_filter_d2api(sp->ps_templ, filtp);                		/* Move TSpec or empty object */		filtp = (API_FilterSpec *)				       Move_tspec_d2api(sp->ps_tspec, tspecp);		resp->resp_nflwd++;	}	/*	 *	Third pass over PSBs to insert adspec list	 */	adsp = (API_Adspec *) filtp;	for (sp = destp->d_PSB_list; sp != NULL; sp = sp->ps_next) {		if (mode != UPCALL_MODE_STAT && IsHopAPI(&sp->ps_phop))			continue;		adsp = (API_Adspec *) Move_adspec_d2api(sp->ps_adspec, adsp);	}	upcall_to_appl(resp, (char *) adsp - resp_buf, NULL, sid);	/*	 *	If notifying of PATH state and there was a         *	pending Resv from API, retry Resv immediately.	 */	if (mode == UPCALL_MODE_PATH) {            for(sid = 0; sid < API_TABLE_SIZE; sid++) {                api_rec *recp = &api_table[sid];		if (resp->resp_nflwd && recp->api_r_packet.pkt_data)			rsvp_pkt_process(&recp->api_r_packet, NULL, api_num);	    }	}	free(resp_buf);}/* * api_PATH_ERR_upcall: Pass Path Error message across API to all *			application(s) that match it. */voidapi_PATH_ERR_upcall(struct packet *pkt)	{	char		resp_buf[MAX_PKT];	rsvp_resp	*resp = (rsvp_resp *) resp_buf;	API_FilterSpec	*api_filtp = (API_FilterSpec *) &resp->resp_flows;	API_TSpec	*api_tspecp;	SenderDesc	*sdscp = SenderDesc_of(pkt);	FORCE_HOST_ORDER(pkt);	memset(resp, 0, MAX_PKT);	/* Excessive... */	resp->resp_type = RAPI_PATH_ERROR;	api_ERR_upcall_common(resp, pkt);	assert(pkt->rsvp_nflwd <= 1);	if (pkt->rsvp_nflwd < 1)		return;	resp->resp_nflwd = 1; 	api_tspecp = (API_TSpec *)			Move_filter_d2api(sdscp->rsvp_stempl, api_filtp);	api_filtp = (API_FilterSpec *)			Move_tspec_d2api(sdscp->rsvp_stspec, api_tspecp);		upcall_to_appl(resp, (char *)api_filtp - resp_buf, sdscp->rsvp_stempl,								ALL_SID);}voidapi_RESV_EVENT_upcall(Session *destp, RSB *rp) {	api_RESV_EVENT_upcall1(destp, rp, 0);}voidapi_RESV_EVENT_upcall_stat(Session *destp, RSB *rp) {	api_RESV_EVENT_upcall1(destp, rp, 1);}/* *  api_RESV_EVENT_upcall1() [Inner routine] * *	Make RESV_EVENT upcall to application for specific RSB. *	If is_stat is non-zero, use STATUS type in response msg. */voidapi_RESV_EVENT_upcall1(Session *destp, RSB *rp, int is_stat)	{	char		 resp_buf[MAX_PKT];	rsvp_resp	*resp = (rsvp_resp *) resp_buf;	API_Flowspec	*api_specp;	API_FilterSpec	*api_filtp;	int		 i;	memset(resp, 0, MAX_PKT);	resp->resp_type = (is_stat)? RAPI_RESV_STATUS: RAPI_RESV_EVENT;	resp_session_assign(resp,destp->d_session);	/*	Map style into external style id	 */	switch (rp->rs_style) {		case STYLE_WF:			resp->resp_style = RAPI_RSTYLE_WILDCARD;			break;		case STYLE_FF:			resp->resp_style = RAPI_RSTYLE_FIXED;				break;		case STYLE_SE:			resp->resp_style = RAPI_RSTYLE_SE;			break;		default:			assert(0);	}	api_filtp = (API_FilterSpec *) resp->resp_flows;        if (rp->rs_spec == NULL) {		resp->resp_nflwd = 0;                upcall_to_appl(resp, (char *)api_filtp-resp_buf,NULL,ALL_SID);                return;        }        /* 	After rq_policy in API response comes pair:         *              Style=WF: <NUL,Q>         *              Style=FF: <F,Q>         *              Style=SE: <F,Q>	 *	Note that only one flowspec is passed per upcall; one FF	 *	style Resv may produce multiple upcalls.  Furthermore, only	 *	the matching filter spec is passed for SE.  But if state	 * 	has been torn down, make empty upcall.         */	resp->resp_nflwd = 1;	if (resp->resp_style == RAPI_RSTYLE_WILDCARD) {        	api_specp = (API_Flowspec *)				Move_filter_d2api(NULL, api_filtp);		api_filtp = (API_FilterSpec *)				Move_spec_d2api(rp->rs_spec, api_specp);		upcall_to_appl(resp, (char *) api_filtp-resp_buf,NULL,ALL_SID);		return;	}	for (i = 0; i < rp->rs_fcount; i++) {        	api_specp = (API_Flowspec *)				Move_filter_d2api(rp->rs_Filtp(i), api_filtp);		api_filtp = (API_FilterSpec *)				Move_spec_d2api(rp->rs_spec, api_specp);		upcall_to_appl(resp, (char *) api_filtp - resp_buf, 						rp->rs_Filtp(i), ALL_SID);	}}/*	api_RESV_ERR_upcall:  Send reservation error or confirmation to *		all applications matching session. */voidapi_RESV_ERR_upcall(struct packet *pkt)	{	char            resp_buf[MAX_PKT];	rsvp_resp      *resp = (rsvp_resp *) resp_buf;	int             i;	API_FilterSpec	*api_filtp = (API_FilterSpec *) &resp->resp_flows;	API_Flowspec 	*api_specp;	FORCE_HOST_ORDER(pkt);	memset(resp, 0, MAX_PKT);	/* Excessive... */	resp->resp_type = (errorspec_get_errcode(pkt->rsvp_errs)					== RSVP_Err_NONE)?					RAPI_RESV_CONFIRM:					RAPI_RESV_ERROR;	api_ERR_upcall_common(resp, pkt);	/*	Map style into external style id	 */	switch (Style(pkt)) {		case STYLE_WF:			resp->resp_style = RAPI_RSTYLE_WILDCARD;			break;		case STYLE_FF:			resp->resp_style = RAPI_RSTYLE_FIXED;				break;		case STYLE_SE:			resp->resp_style = RAPI_RSTYLE_SE;			break;		default:			assert(0);	}		resp->resp_nflwd = pkt->rsvp_nflwd;	for (i = 0; i < pkt->rsvp_nflwd; i++) {		FlowDesc *flwdp = FlowDesc_of(pkt, i);		api_specp = (API_Flowspec *)                 				Move_filter_d2api(flwdp->rsvp_filtp, api_filtp);                api_filtp = (API_FilterSpec *)			Move_spec_d2api(flwdp->rsvp_specp, api_specp);	}	upcall_to_appl(resp, (char *) api_filtp - resp_buf, NULL, ALL_SID);}voidapi_ERR_upcall_common(rsvp_resp *resp, struct packet *pkt)	{	SESSION *session = pkt->rsvp_sess;	ERROR_SPEC *errorspec = pkt->rsvp_errs;	if (Obj_Class(session) != class_SESSION)		return;	if (Obj_Class(errorspec) != class_ERROR_SPEC)		return;	resp_session_assign(resp, session);	switch(Obj_CType(session)) {		case ctype_SESSION_ipv4:		case ctype_SESSION_ipv4GPI:			if (Obj_CType(errorspec) != ctype_ERROR_SPEC_ipv4)				return;			resp->resp_errcode = errorspec->errspec4_code;			resp->resp_errval =  errorspec->errspec4_value;			resp->resp_errflags = errorspec->errspec4_flags;			NET_SOCKADDR_IPv4(				(struct sockaddr_in *) &resp->resp_errnode,				errorspec->errspec4_enode);			return;#ifdef	USE_IPV6		case ctype_SESSION_ipv6:		case ctype_SESSION_ipv6GPI:			if (Obj_CType(errorspec) != ctype_ERROR_SPEC_ipv6)				return;			resp->resp_errcode = errorspec->errspec6_code;			resp->resp_errval =  errorspec->errspec6_value;			resp->resp_errflags = errorspec->errspec6_flags;			NET_SOCKADDR_IPv6(				(struct sockaddr_in6 *) &resp->resp_errnode,				errorspec->errspec6_enode);			return;#endif	/* USE_IPV6 */		default:			return;	}}staticintresp_session_assign(rsvp_resp *resp,SESSION *session)	{	if (Obj_Class(session) != class_SESSION)		return(FALSE);	resp->resp_flags = 0;	switch(Obj_CType(session)) {		case ctype_SESSION_ipv4GPI:			resp->resp_flags |= RAPI_GPI_SESSION;		case ctype_SESSION_ipv4:			resp->resp_dest.type = htons(API_ADDR_TYPE_IPv4);			resp->resp_dest.port = session->sess4_port;			memcpy(&resp->resp_dest.u.addr_ipv4,				&session->sess4_addr,				sizeof(resp->resp_dest.u.addr_ipv4));			resp->resp_protid = session->sess4_prot;			return(TRUE);#ifdef	USE_IPV6		case ctype_SESSION_ipv6GPI:			resp->resp_flags |= RAPI_GPI_SESSION;		case ctype_SESSION_ipv6:			resp->resp_dest.type = htons(API_ADDR_TYPE_IPv6);			resp->resp_dest.port = session->sess6_port;			memcpy(&resp->resp_dest.u.addr_ipv6,				&session->sess6_addr,				sizeof(resp->resp_dest.u.addr_ipv6));			resp->resp_protid = session->sess6_prot;			return(TRUE);#endif	/* USE_IPV6 */		default:			return(FALSE);	}}/*	Vector of direction flags for each event type. */static int  DIR_per_EVENT[] = {0,		0,		/* 1- Path event: OK even if dir not set */		API_DIR_SEND,	/* 2- Resv event */		API_DIR_SEND,	/* 3- Path error event */		API_DIR_RECV,	/* 4- Resv error event */		API_DIR_RECV,	/* 5- Confirmation event */		0, 0, 0,		0,		/* 9- Path status	*/		API_DIR_SEND	/* 10- Resv status	*/	};/*	Given response message, pass it to specified API session.  If *	sid = -1 (ALL_SID), pass it to all API sessions with matching *	session and direction, and for FILTER_SPEC *filtp matching sender *	if filtp is not NULL.  Otherwise, pass to specific sid. *	 */static voidupcall_to_appl(rsvp_resp *resp, int len, FILTER_SPEC *filtp, int sid)	{	api_rec *recp;	net_addr dest;	resp->resp_version = VERSION_API;	if (sid >= 0) {		upcall_to_sid(resp, len, sid);		return;	}	net_addr_assign_api_addr(&dest,&resp->resp_dest,1);	for(sid = 0; sid < API_TABLE_SIZE; sid++) {		recp = &api_table[sid];		if (recp->api_fd == 0)			continue;		if (DIR_per_EVENT[resp->resp_type] &&		   (recp->api_flags & DIR_per_EVENT[resp->resp_type]) == 0)			continue;		if (filtp) {			if (!recp->api_p_packet.pkt_data)				continue;			else if (!match_filter(filtp,			      (SenderDesc_of(&recp->api_p_packet))->rsvp_stempl))				continue;		}		if (net_addr_equal(&dest, &recp->api_dest)		 	&& (resp->resp_protid == recp->api_protid))				upcall_to_sid(resp, len, sid);	}}/*	Given response message and length, send as upcall to specified *	API session (inner routine of upcall_to_appl()) */void upcall_to_sid(rsvp_resp *resp, int len, int sid) {	api_rec *recp = &api_table[sid];	resp->resp_a_sid = recp->api_a_sid; /* Client's SID */	if (IsDebug(DEBUG_ALL)) {		static char  *Event_Names[] = { "",		 "Path Evt", "Resv Evt", "Perr Evt", "Rerr Evt",		  "RConfirm", "??6 Ev",   "??7 Ev",   "??8 Ev",		  "Pstat Ev", "Rstat Ev"};		net_addr dest;		net_addr_assign_api_addr(&dest,&resp->resp_dest,1);		log_api_event(LOGEV_API_upcall, 			Event_Names[resp->resp_type],			&dest, resp->resp_protid,			"> API pid=%d Asid=%d\n",			recp->api_pid, recp->api_a_sid);	}	if (NetByteOrderResp(sid)) {		char *newbuf = malloc(len);		if (!newbuf)				return;		memcpy(newbuf, (char *)resp, len);		hton_api_resp((rsvp_resp *)newbuf, len);		send_to_api(sid, (rsvp_resp *)newbuf, len);		free(newbuf);	} else		send_to_api(sid, resp, len);}/* *  Write message 'resp' of length 'len' bytes across API to application *  with local session id 'sid'. * */voidsend_to_api(int sid, rsvp_resp *resp, int len)	{	struct iovec iov[2];	int nlen = len;	if (l_debug >= LOG_HEXD && len > 0) {		hexf(stderr, (char *) resp, len);	}	if (NetByteOrderResp(sid))		HTON32(nlen);	iov[0].iov_base = (char *) (&nlen); 	iov[0].iov_len  = sizeof(int); 	iov[1].iov_base = (char *) resp; 	iov[1].iov_len  = len;         	if (writev(api_table[sid].api_fd, iov, 2) == -1)  {		log(LOG_ERR, errno, "NBIO write error\n"); 	}}intapi_refresh_delay(int sid)	{	api_rec *recp = &api_table[sid];	if (recp->api_p_packet.pkt_data)		return ((&recp->api_p_packet)->rsvp_R);	else if (recp->api_r_packet.pkt_data)		return ((&recp->api_r_packet)->rsvp_R);	else		return (0);}Session *locate_api_session(rsvp_req *req, int gpi)	{	SESSION Session_obj;	net_addr dest;	net_addr_assign_api_addr(&dest,&req->rq_dest,1);	session_create(&Session_obj,&dest,		(req->rq_protid)?req->rq_protid:RSVP_DFLT_PROTID,0,gpi);	return(locate_session(&Session_obj));}voidlog_api_event(int evtype, char *type, net_addr *adrp, int protid,		const char *format, int pid, int asid)	{	SESSION Session_obj;	session_create(&Session_obj,adrp,protid,0,FALSE);	log_event(evtype, type, &Session_obj, format, pid, asid);}static voidprint_api_request(rsvp_req *req, int len, int sid)	{	api_rec		*recp = &api_table[sid];

⌨️ 快捷键说明

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