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

📄 scrapi.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	s->status &= ~S_RECV_REQUESTS;	s->status |= status;	s->spec.specbody_qosx.spec_type = service;}/****************************************************************************** * *	Machinery to make reservations. * *****************************************************************************/staticvoidsend_reservations_shared(rapi_sid_t sid,int n,rapi_flowspec_t *spec){	int i;	session *sp;	sender *s;	rapi_filter_t *filter;	sp = &sessions[sid];	filter = (rapi_filter_t *) malloc(n * sizeof(rapi_filter_t));	i = 0;	for (s = sp->flows;s != NULL;s = s->next) {		if (!(s->status & S_PATH))			continue;		if (!(s->status & S_RESV_REQUEST))			continue;		filter[i] = s->src;		spec[i++] = s->spec;	}	sp->errno = map_errno[rapi_reserve(sid,RAPI_REQ_CONFIRM,NULL,		RAPI_RSTYLE_SE,NULL,NULL,n,filter,1,spec)];	free(filter);}staticvoidsend_reservations_distinct(rapi_sid_t sid,int n){	int i;	session *sp;	sender *s;	rapi_filter_t *filter;	rapi_flowspec_t *spec;	sp = &sessions[sid];	filter = (rapi_filter_t *) malloc(n * sizeof(rapi_filter_t));	spec = (rapi_flowspec_t *) malloc(n * sizeof(rapi_flowspec_t));	i = 0;	for (s = sp->flows;s != NULL;s = s->next) {		if (!(s->status & S_PATH))			continue;		if (!(s->status & S_RESV_REQUEST))			continue;		filter[i] = s->src;		spec[i++] = s->spec;	}	sp->errno = map_errno[rapi_reserve(sid,RAPI_REQ_CONFIRM,NULL,		RAPI_RSTYLE_FIXED,NULL,NULL,n,filter,n,spec)];	free(filter);	free(spec);}staticvoidsend_reservations(rapi_sid_t sid){	int nflows,nreqs;	session *sp;	sender *s;	rapi_flowspec_t spec;	qos_flowspecx_t *q = &spec.specbody_qosx;	sp = &sessions[sid];	Object_Type(&spec) = RAPI_FLOWSTYPE_Simplified;	Object_Length(&spec) = sizeof(rapi_flowspec_t);	q->spec_type = sp->service;	q->xspec_r = 0;	q->xspec_R = 0;	q->xspec_S = ULONG_MAX;	q->xspec_b = 0;	q->xspec_p = 0;	q->xspec_m = ULONG_MAX;	q->xspec_M = 0;	nflows = 0;	nreqs = 0;	for (s = sp->flows;s != NULL;s = s->next) {		if (!(s->status & S_PATH))			continue;		nflows++;		if (!(s->status & S_RESV_REQUEST))			continue;		q->xspec_r = C_MAX(q->xspec_r,s->spec.specbody_qosx.xspec_r);		q->xspec_R = C_MAX(q->xspec_R,s->spec.specbody_qosx.xspec_r);		q->xspec_S = C_MIN(q->xspec_S,s->spec.specbody_qosx.xspec_S);		q->xspec_b = C_MAX(q->xspec_b,s->spec.specbody_qosx.xspec_b);		q->xspec_p = C_MAX(q->xspec_p,s->spec.specbody_qosx.xspec_p);		q->xspec_m = C_MIN(q->xspec_m,s->spec.specbody_qosx.xspec_m);		q->xspec_M = C_MAX(q->xspec_M,s->spec.specbody_qosx.xspec_M);		nreqs++;	}	if (nreqs == 0) {		sp->errno = map_errno[rapi_reserve(sid,0,NULL,			RAPI_RSTYLE_SE,NULL,NULL,0,NULL,0,NULL)];		return;	}	switch (sp->style) {		case scrapi_style_distinct:			send_reservations_distinct(sid,nreqs);			break;		case scrapi_style_shared:			if (nflows == nreqs)				sp->errno = map_errno[rapi_reserve(sid,					RAPI_REQ_CONFIRM,NULL,					RAPI_RSTYLE_WILDCARD,NULL,NULL,					0,NULL,1,&spec)];			else				send_reservations_shared(sid,nreqs,&spec);			break;		default:	}}staticintcallback(rapi_sid_t sid,rapi_eventinfo_t event,int style,	int errcode,int errval,struct sockaddr *errnode,u_char errflag,	int nfilts,rapi_filter_t *filt,int nspecs,rapi_flowspec_t *spec,	int nadspecs,rapi_adspec_t *adspec,void *data){	int i;	session *sp;	sender *s;	static void print_callback(rapi_sid_t,rapi_eventinfo_t,int,int,int,		struct sockaddr *,u_char,int, rapi_filter_t *,int,		rapi_flowspec_t *,int,rapi_adspec_t *,void *);	if (dout) {		print_callback(sid,event,style,errcode,errval,errnode,errflag,			nfilts,filt,nspecs,spec,nadspecs,adspec,data);	}	sp = &sessions[sid];	switch (event) {		case RAPI_PATH_EVENT:			break;		case RAPI_RESV_EVENT:			if (nspecs == 0)				sp->status &= ~S_RESV;			else {				sp->status |= S_RESV;				sp->status &= ~S_PATH_ERROR;			}			return(0);		case RAPI_RESV_CONFIRM:			sp->status |= S_CONFIRM;			sp->status &= ~S_RESV_ERROR;			if (filt != NULL) {				s = get_sender(sid,filt);				s->status |= S_CONFIRM;				s->status &= ~S_RESV_ERROR;			}			return(0);		case RAPI_PATH_ERROR:			sp->status |= S_PATH_ERROR;			return(0);		case RAPI_RESV_ERROR:			sp->status |= S_RESV_ERROR;			sp->status &= ~S_CONFIRM;			if (filt != NULL) {				s = get_sender(sid,filt);				s->status |= S_RESV_ERROR;				s->status &= ~S_CONFIRM;			}			return(0);		default:			return(0);	}	for (s = sp->flows;s != NULL;s = s->next)		s->status &= ~S_PATH;	nspecs = C_MIN(nspecs,nfilts);	for (i = 0;i < nspecs; i++) {		if (Object_Type(spec) != RAPI_TSPECTYPE_Simplified)			continue;		set_sender(sid,filt,spec);		spec = Object_Next(rapi_flowspec_t,spec);		filt = Object_Next(rapi_filter_t,filt);	}	for (s = sp->flows;s != NULL;s = s->next)		if (!(s->status & S_PATH))			s->status &= ~S_RECV_NOT_REQUESTS;	if (nspecs == 0)		sp->status &= ~S_RECV_NOT_REQUESTS;	send_reservations(sid);	return(0);}/****************************************************************************** * *	Utility functions for session information. * *****************************************************************************/staticrapi_sid_tfind_session(const struct sockaddr *dst,int proto,const struct sockaddr *src){	int i;	session *sp;	for (i = 0;i < MAXSESSIONS; i++) {		sp = &sessions[i];		if (!(sp->status & S_OPEN))			continue;		if (!sockaddr_equal(dst,SAP(&sp->dst)))			continue;		if (proto != sp->proto)			continue;		if (sockaddr_equal(src,SAP(&sp->src)))			return(i);	}	return(NULL_SID);}staticrapi_sid_tget_session(const struct sockaddr *dst,int proto,const struct sockaddr *src){	int error;	rapi_sid_t sid;	session *sp;	sid = find_session(dst,proto,src);	if (sid != NULL_SID)		return(sid);	sid = rapi_session(SAP(dst),proto,0,&callback,NULL,&error);	if (sid >= MAXSESSIONS)		return(NULL_SID);	/* FIX: map sids to index values in sessions[] */	sp = &sessions[sid];	sockaddr_assign(SAP(&sp->dst),dst);	sp->proto = proto;	sockaddr_assign(SAP(&sp->src),src);	sp->flows = NULL;	sp->errno = map_errno[error];	if (sid != NULL_SID) {		sp->status = S_OPEN;		nsessions++;	}	return(sid);}staticintclose_session(rapi_sid_t sid){	session *sp;	sender *s,*next;	sp = &sessions[sid];	for (s = sp->flows;s != NULL;s = next) {		next = s->next;		free(s);	}	sp->status = S_NONE;	nsessions--;	return(rapi_release(sid) == RAPI_ERR_OK);}staticintclose_inactive_session(rapi_sid_t sid){	session *sp;	sender *s;	sp = &sessions[sid];	if (sp->status & S_REQUESTS)		return(TRUE);	for (s = sp->flows;s != NULL;s = s->next)		if (s->status & S_REQUESTS)			return(TRUE);	return(close_session(sid));}/****************************************************************************** * *	Miscellaneous utility functions. * *****************************************************************************/staticintdispatch(rapi_sid_t sid){	int error;	error = rapi_dispatch();	if (error == RAPI_ERR_OK)		return(TRUE);	sessions[sid].errno = map_errno[error];	close_inactive_session(sid);	return(FALSE);}staticintbad_parameter(rapi_sid_t sid){	sessions[sid].errno = SCRAPI_ERRNO_PARAM;	close_inactive_session(sid);	return(FALSE);}staticinttimed_wait(rapi_sid_t sid,unsigned long flags,unsigned long msecs){	int n;	session *sp;	struct timeval tv,tv1,tv2;	fd_set rfds;	if (msecs == 0)		return(TRUE);	tv.tv_sec = msecs / 1000;	tv.tv_usec = 1000 * (msecs - 1000 * (msecs / 1000));	FD_ZERO(&rfds);	FD_SET(rapi_getfd(sid),&rfds);	sp = &sessions[sid];	do {		if (!dispatch(sid))			return(FALSE);		if (sp->status & flags)			return(TRUE);		if (sp->status & S_ERRORS) {			sp->errno = SCRAPI_ERRNO_NONE;			return(FALSE);		}		tv2 = tv;		gettimeofday(&tv1,NULL);		n = select(FD_SETSIZE,&rfds,(fd_set *) NULL,			(fd_set *) NULL,&tv2);		gettimeofday(&tv2,NULL);		tv.tv_sec -= tv2.tv_sec - tv1.tv_sec; 		tv.tv_usec -= tv2.tv_usec - tv1.tv_usec; 	} while (n == 1);	sp->errno = SCRAPI_ERRNO_TIMEOUT;	return(FALSE);}/* *	This is unfortunately very system dependent! */staticunsigned intmax_packet_size(){	int fd,mtu = MAX_PACKET_SIZE;	struct ifconf ifc;	struct ifreq ifr,*p,*last;	static char buffer[MAX_INTERFACES * sizeof(struct ifreq)		+ sizeof(struct ifconf)];	fd = socket(AF_INET,SOCK_DGRAM,PF_UNSPEC);	if (FAILED(fd))		return(mtu);	ifc.ifc_buf = buffer;	ifc.ifc_len = sizeof(buffer);	if (FAILED(ioctl(fd,SIOCGIFCONF,(caddr_t) &ifc))) {		close(fd);		return(mtu);	}	last = ((struct ifreq *) ifc.ifc_req) + ifc.ifc_len;	for (p = (struct ifreq *) ifc.ifc_req;p < last;#ifdef	__FreeBSD__			p = (struct ifreq *) (((char *) &p->ifr_addr)			+ p->ifr_addr.sa_len)) {#else	/* __FreeBSD__ */			p++) {#endif	/* __FreeBSD__ */		if (strncmp(p->ifr_name,"",IFNAMSIZ) == 0)			break;		if (strncmp(p->ifr_name,"lo0",IFNAMSIZ) == 0)			continue;		switch (p->ifr_addr.sa_family) {			case AF_INET:#ifdef	USE_IPV6			case AF_INET6:#endif	/* USE_IPV6 */				break;			default:				continue;		}		strncpy(ifr.ifr_name,p->ifr_name,IFNAMSIZ);		if (FAILED(ioctl(fd,SIOCGIFMTU,(caddr_t) &ifr)))			continue;		mtu = C_MAX(mtu,ifr.ifr_metric);	}	close(fd);	return(mtu);}/****************************************************************************** * *	Simplified RAPI inteface. * *****************************************************************************/intscrapi_sender(const struct sockaddr *dst,int proto,	const struct sockaddr *src,double bw,int ttl,unsigned long msecs){	rapi_sid_t sid;	session *sp;	rapi_tspec_t tspec;	qos_tspecx_t *q = &tspec.tspecbody_qosx;	struct SOCKADDR any;	if (!scrapi_sockaddr_any(SAP(&any),dst->sa_family))		return(FALSE);	if ((src == NULL) || sockaddr_equal(src,SAP(&any))) {		sid = get_session(dst,proto,SAP(&any));		if (sid == NULL_SID)			return(FALSE);		return(bad_parameter(sid));	}	sid = get_session(dst,proto,src);	if (sid == NULL_SID)		return(FALSE);	if (!dispatch(sid))		return(FALSE);	if (bw == 0)		return(close_session(sid));	sp = &sessions[sid];	sp->status &= ~S_SEND_REQUESTS;	sp->status |= S_PATH_REQUEST;	q->spec_type = QOS_TSPEC;	q->xtspec_r = bw;	q->xtspec_b = 2 * bw;	q->xtspec_p = 2 * bw;	q->xtspec_m = MIN_PACKET_SIZE;	q->xtspec_M = max_packet_size();	tspec.form = RAPI_TSPECTYPE_Simplified;	tspec.len = sizeof(rapi_hdr_t) + sizeof(qos_tspecx_t);	sp->errno = map_errno[rapi_sender(sid,0,SAP(src),		filter_from_sockaddr(src),&tspec,NULL,NULL,ttl)];	if (sp->errno != SCRAPI_ERRNO_NONE) {		close_session(sid);		return(FALSE);	}	return(timed_wait(sid,S_RESV,msecs));}intscrapi_receiver(const struct sockaddr *dst,int proto,	const struct sockaddr *src,int on,scrapi_service service,	scrapi_style style,unsigned long msecs){	rapi_sid_t sid;	session *sp;	sender *s;	rapi_filter_t *f;	enum qos_service_type serv;	struct SOCKADDR any;	unsigned long status;	if (!scrapi_sockaddr_any(SAP(&any),dst->sa_family))		return(FALSE);	if (src == NULL)		src = SAP(&any);	sid = get_session(dst,proto,src);	if (sid == NULL_SID)		return(FALSE);	if (!dispatch(sid))		return(FALSE);	if (scrapi_sockaddr_get_port(src) != htons(0))		if (sockaddr_equal_wild(src,SAP(&any)))			return(bad_parameter(sid));	switch (service) {		case scrapi_service_cl:			serv = QOS_CNTR_LOAD;			break;		case scrapi_service_gs:			serv = QOS_GUARANTEED;			break;		default:			return(bad_parameter(sid));	}	if (!sockaddr_equal(src,SAP(&any))) {		close_inactive_session(sid);		sid = get_session(dst,proto,SAP(&any));		if (sid == NULL_SID)			return(FALSE);	}	sp = &sessions[sid];	sp->service = serv;	sp->style = style;	status = on ? S_RESV_REQUEST : S_NONE;	f = filter_from_sockaddr(src);	mod_sender(get_sender(sid,f),sp->service,status);	if (sockaddr_equal(src,SAP(&any))) {		/*		 *	Apply the wild src to all sources.		 */		for (s = sp->flows;s != NULL;s = s->next)			mod_sender(s,sp->service,status);	}	else {		/*		 *	Apply the wild src port to all sources with the		 *	same address.		 */		if (scrapi_sockaddr_get_port(src) == htons(0))			for (s = sp->flows;s != NULL;s = s->next) {				if (!filter_equal_wild(f,&s->src))					continue;				mod_sender(s,sp->service,status);			}	}	send_reservations(sid);	if (on)		return(timed_wait(sid,S_CONFIRM,msecs));	return(close_inactive_session(sid));}intscrapi_close(const struct sockaddr *dst,int proto,	const struct sockaddr *src){	int i,ret = TRUE;	rapi_sid_t sid;	session *sp;	struct SOCKADDR any;	if (dst != NULL) {		if (!scrapi_sockaddr_any(SAP(&any),dst->sa_family))			return(FALSE);	}	if ((dst == NULL) || sockaddr_equal(dst,SAP(&any))) {		for (i = 0;i < MAXSESSIONS; i++)			if (sessions[i].status & S_OPEN)				ret |= close_session(i);		return(ret);	}	sid = find_session(dst,proto,SAP(&any));	if (sid != NULL_SID) {		sp = &sessions[sid];		/* FIX: doesn't take wild address */		scrapi_receiver(dst,proto,src,FALSE,sp->service,sp->style,0);	}	if ((src == NULL) || sockaddr_equal(src,SAP(&any))) {		if (!dispatch(sid))			return(FALSE);		for (i = 0;i < MAXSESSIONS; i++) {			if (i == sid)				continue;			sp = &sessions[i];			if (!(sp->status & S_OPEN))				continue;			if (!sockaddr_equal(dst,SAP(&sp->dst)))				continue;			if (proto != sp->proto)				continue;			ret |= close_session(i);		}		return(ret);	}	/* FIX: doesn't take wild port */	sid = find_session(dst,proto,src);	if (sid != NULL_SID) {		if (!dispatch(sid))			return(FALSE);		return(close_session(sid));	}	return(ret);}intscrapi_dispatch(){	int error;	rapi_sid_t sid;	struct SOCKADDR host;	if (nsessions == 0) {		if (!scrapi_sockaddr_parse(SAP(&host),"10.0.0.1",htons(1)))			return(FALSE);		sid = rapi_session(SAP(&host),IPPROTO_UDP,0,&callback,			NULL,&error);		if (sid == NULL_SID)			return(FALSE);		rapi_release(sid);		return(TRUE);	}	return(rapi_dispatch() != RAPI_ERR_NORSVP);}voidscrapi_poll_list(fd_set *set){	int i;

⌨️ 快捷键说明

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