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

📄 rsvp_timer.c

📁 radius协议源码÷The Radius Stack will connect to a Radius Server. This stack implementation is built upo
💻 C
字号:
/* * @(#) $Id: rsvp_timer.c,v 1.1.1.1 2000/05/08 22:51:24 wenqing Exp $ *//************************ rsvp_timer.c *************************** *                                                               * *  Timer package for the RSVP daemon (rsvpd)                    * *                                                               * *****************************************************************//****************************************************************************            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.********************************************************************//* * This timer package is based on * virtual time in miliseconds and on the assumption that there exists a * current time (time_now). The queue is ordered by decreasing time values, * and the q. is examined once in a time slice (granularity of the timer). * When events are due, they are executed. */#include "rsvp_daemon.h"/*	Timer queue element structure */typedef struct Time_rec {	struct Time_rec *next;	unsigned long   due_time;	char           *user_ptr;	int             user_data;}   time_rec;static time_rec *time_q = NULL, *free_q = NULL;unsigned long   time_now = 0;/* external declarations */extern int	resv_refresh_TimeOut(), path_refresh();extern int	refresh_api();extern int	api_refresh_delay(int);extern void	rtap_sleepdone();extern int	refresh_default;/* forward declarations */void		del_from_timer(char *, int);static time_rec *find_timer(void *, int);void		print_timer_record(time_rec *tp);int		RandomDelay(int);/* * init_timer(): initializes the timer data structures.  */intinit_timer(int q_size) {	int             i;	time_q = NULL;	free_q = (time_rec *) calloc((unsigned) q_size, sizeof(time_rec));	if (free_q == NULL) {		log(LOG_ERR, 0, "Memory allocation for timer queue", 0);		exit(1);	}	for (i = 0; i < q_size; i++)	/* chain all the free together */		free_q[i].next = &(free_q[i + 1]);	free_q[q_size - 1].next = NULL;	return(0);}/* * add_to_timer():   Enters event into timer queue, in order by expiration. *	An event is identified by two values: A pointer and an integer. *	The pointer points to data related to the event, and the integer *	has flags to determin the type of the event (path, resv etc). */voidadd_to_timer(user_ptr, user_data, delay)	char		*user_ptr;	/* a pointer to status  */	int		user_data;	/* and integer flags    */	int		delay;{	time_rec	**t, *tmp;	unsigned long	due;	assert(delay >= 0);	/*	 *  If this event already exists with a smaller due time,	 *  then just return	 */	tmp = find_timer(user_ptr, user_data);	if (tmp) {		if (IsDebug(DEBUG_TIMERS)) {			log(LOG_DEBUG, 0, "Event already exists ...\n");			print_timer_record(tmp);		}		if (LTE(tmp->due_time, time_now+delay))			return;		else			del_from_timer(user_ptr, user_data);	}	if ((tmp = free_q) == NULL) {	/* no more q. records   */		log(LOG_WARNING, 0, "No free queue records", 0);		assert(free_q != NULL);		/* i.e. abort() */		return;	}	free_q = free_q->next;	/* get if off the free list */	tmp->due_time = due = time_now + delay;	tmp->user_ptr = user_ptr;	tmp->user_data = user_data;	for (t = &time_q; *t != NULL && LTE((*t)->due_time, due);	     t = &((*t)->next));	tmp->next = *t;	*t = tmp;	if (IsDebug(DEBUG_TIMERS)) {		log(LOG_DEBUG, 0, "Added timer event - ");		print_timer_record(tmp);		timer_print();	}}/* * del_from_timer():  Delete an event from the timer queue before its *	expiration time. */voiddel_from_timer(user_ptr, user_data)	char           *user_ptr;	/* a pointer to status  */	int             user_data;	/* and integer flags    */{	time_rec      **t, *tmp;	for (t = &time_q; (*t) != NULL;) {		if ((*t)->user_ptr != user_ptr || (*t)->user_data != user_data)			t = &((*t)->next);		else {		/* found a record to delete */			tmp = *t;		/* unchain it  */			*t = (*t)->next;			tmp->next = free_q;	/* insert into free list   */			free_q = tmp;			if (IsDebug(DEBUG_TIMERS)) {				log(LOG_DEBUG, 0, "Deleted timer event - ");				print_timer_record(tmp);			}		}	}}static time_rec *find_timer(void *ptr, int code) {	time_rec *tp;	for (tp = time_q; tp; tp = tp->next) {		if (tp->user_data == code && tp->user_ptr == (char *)ptr)			return(tp);	}	return(tp);}/* * timer_wakeup():  Awakened periodically from select (period = granularity), *	to dequeue and execute all expired events in timer queue. */voidtimer_wakeup(int sig) {	/* Activate all expired events */	while (time_q != NULL && LTE(time_q->due_time, time_now)) {		time_rec *t = time_q;		time_q = time_q->next;	/* get it off the time_q and */		t->next = free_q;	/* into the free list        */		free_q = t;		if (IsDebug(DEBUG_TIMERS)) {			log(LOG_DEBUG, 0, "Activate timer event - ");			print_timer_record(t);			timer_print();		}		timer_signal(t->user_ptr, t->user_data);	}}u_longnext_event_time() {	if (time_q)		return(time_q->due_time);	else		return(-1);}/* * timer_signal(): Execute expired event. */inttimer_signal(user_ptr, user_data)	char           *user_ptr;	int             user_data;{	int             type = user_data & 0xff;	int		rc, delay;	Session		*destp;	Log_Event_Cause = "T";	switch (type) {	    case TIMEV_API:		/*  Refresh information from API.		 * 	 user_ptr is the SID which indexes rsvp_vec[]		 */		rc = refresh_api((int) user_ptr);		delay = api_refresh_delay((int) user_ptr);		break;	    case TIMEV_PATH:		/*  Send Path refresh message(s) for specific destination.		 *	refresh_path -> -1 if the dest expired (ttd arrived)		 */		destp = (Session *)user_ptr;		rc = path_refresh(destp);/*** experimental code		if (destp->d_refr_p.d_fast_n > 0) {			destp->d_refr_p.d_fast_n--;			delay = REFRESH_FAST_T;		}		else ***/		if (!rc) 			delay = (int) RandomDelay(destp->d_Rtimop);		break;	    case TIMEV_RESV:		/* Send Resv refresh messages(s) for specific destination.		 *	resv_refresh -> -1 if the dest expired (ttd arrived)		 */		destp = (Session *)user_ptr;		rc = resv_refresh_TimeOut(destp); 		delay = (int) RandomDelay(destp->d_Rtimor);		break;	    case TIMEV_LocalRepair:		/*	Delay of W seconds has passed to allow routing		 *	protocol to settle down.  Now refresh Path state.		 */		destp = (Session *)user_ptr;		rc = path_refresh(destp);		delay = -1;	/* Do NOT reschedule */		break;	#ifdef RTAP	    case TIMEV_RTAPsleep:		/* Sleep command of integral rtap has expired.		 */		rtap_sleepdone();		delay = -1;	/* Do NOT reschedule */		break;#endif	    default:		assert(0);		return(-1);	}	/*	 *	Reschedule event if appropriate	 */	if (rc == 0 && delay > 0)		add_to_timer(user_ptr, user_data, delay);	Log_Event_Cause = NULL;	return(0);}/* * Compute_TTD(): Compute "time-to-die" in internal timer units, *	given ptr to TIME_VALUES struct in Session. * */u_int32_tCompute_TTD(TIME_VALUES *tvp)	{	u_int32_t t, Tval;	Tval = tvp->timev_R;	assert(Tval);	/* Check earlier! */	t = time_now + (K_FACTOR+0.5) * 1.5 * MAX(Tval, MIN_TIMER_PERIOD);	return(t);}/* Compute_R(): Given ptr to appropriate TIME_VALUES struct (in Session *	struct), compute appropriate refresh timeout period and update *	value in Session struct.  Return original value; used as *	'first-time' switch to start timer when state first appears. */u_int32_tCompute_R(TIME_VALUES *tvp)	{	u_int32_t timnew, timold;	timnew = refresh_default;	/*	Base R could depend on load.	 */	if ((timold = tvp->timev_R)) {		/*		 *	Limit slew rate		 */		tvp->timev_R = MIN(timnew, (1+REFRESH_SLEW_MAX)*timold);	}	else		tvp->timev_R = timnew;	return(timold);}voidprint_timer_record(time_rec *tp)	{	Session		*dp;	int           	sid;	int             type = tp->user_data & 0xff;#define XXX_MASK 0xff	int             flags = (tp->user_data >> 8) & XXX_MASK;	int		delta = tp->due_time - time_now;	switch (type) {	case TIMEV_PATH:		dp = (Session *) tp->user_ptr;		log(LOG_DEBUG, 0,"Refresh path %s in %d seconds\n",			session_print(dp->d_session), delta/1000);		break;	case TIMEV_RESV:		dp = (Session *) tp->user_ptr;		log(LOG_DEBUG, 0, "Refresh reservation %s in %d seconds\n",			session_print(dp->d_session), delta/1000);		break;	case TIMEV_API:		sid = (int) (unsigned long) tp->user_ptr;		log(LOG_DEBUG, 0, "Refresh API sid= %d in %d seconds\n", 			sid, delta/1000);		break;	case TIMEV_LocalRepair:		dp = (Session *) tp->user_ptr;		log(LOG_DEBUG, 0,"Local repair %s in %d seconds\n",			session_print(dp->d_session), delta/1000);		break;#ifdef RTAP	case TIMEV_RTAPsleep:		/* Sleep command of integral rtap has expired.		 */		log(LOG_DEBUG, 0, "RTAP sleep in %d seconds\n", delta/1000);		break;	case TIMEV_RTAPdata:		/* It is time to send data		 */#endif	default:		log(LOG_DEBUG, 0, "Unknown timer event %d flags=%d at %d\n",			type, flags, tp->due_time);		break;	}}voidtimer_print(){	time_rec       *tp;	for (tp = time_q; tp != NULL; tp = tp->next) {		print_timer_record(tp);	}}#define RANDOM_RATIO 0.25/* Return random number uniformly distributed in range 0.5A, 1.5A, *	where A ='avgdelay'. */intRandomDelay(int avgdelay)	{	int rand(void);	float del = ((float) rand()/RAND_MAX);	return((int)(avgdelay * (0.5 + del)));}

⌨️ 快捷键说明

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