xref: /csrg-svn/sbin/XNSrouted/timer.c (revision 61474)
124323Ssklower /*
2*61474Sbostic  * Copyright (c) 1985, 1993
3*61474Sbostic  *	The Regents of the University of California.  All rights reserved.
424323Ssklower  *
535551Sbostic  * This file includes significant work done at Cornell University by
635551Sbostic  * Bill Nesheim.  That work included by permission.
735551Sbostic  *
842698Sbostic  * %sccs.include.redist.c%
924323Ssklower  */
1024323Ssklower 
1124314Ssklower #ifndef lint
12*61474Sbostic static char sccsid[] = "@(#)timer.c	8.1 (Berkeley) 06/05/93";
1335551Sbostic #endif /* not lint */
1424314Ssklower 
1524314Ssklower /*
1624314Ssklower  * Routing Table Management Daemon
1724314Ssklower  */
1824314Ssklower #include "defs.h"
1924314Ssklower 
2024314Ssklower int	timeval = -TIMER_RATE;
2124314Ssklower 
2224314Ssklower /*
2324314Ssklower  * Timer routine.  Performs routing information supply
2424314Ssklower  * duties and manages timers on routing table entries.
2524314Ssklower  */
2646705Sbostic void
timer()2724314Ssklower timer()
2824314Ssklower {
2924314Ssklower 	register struct rthash *rh;
3024314Ssklower 	register struct rt_entry *rt;
3124314Ssklower 	struct rthash *base = hosthash;
3224314Ssklower 	int doinghost = 1, timetobroadcast;
3324314Ssklower 
3424314Ssklower 	timeval += TIMER_RATE;
3524314Ssklower 	if (lookforinterfaces && (timeval % CHECK_INTERVAL) == 0)
3624314Ssklower 		ifinit();
3724314Ssklower 	timetobroadcast = supplier && (timeval % SUPPLY_INTERVAL) == 0;
3824314Ssklower again:
3924314Ssklower 	for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) {
4024314Ssklower 		rt = rh->rt_forw;
4124314Ssklower 		for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
4224314Ssklower 			/*
4324314Ssklower 			 * We don't advance time on a routing entry for
4424314Ssklower 			 * a passive gateway or that for our only interface.
4524314Ssklower 			 * The latter is excused because we don't act as
4624314Ssklower 			 * a routing information supplier and hence would
4724314Ssklower 			 * time it out.  This is fair as if it's down
4824314Ssklower 			 * we're cut off from the world anyway and it's
4924314Ssklower 			 * not likely we'll grow any new hardware in
5024314Ssklower 			 * the mean time.
5124314Ssklower 			 */
5224314Ssklower 			if (!(rt->rt_state & RTS_PASSIVE) &&
5324314Ssklower 			    (supplier || !(rt->rt_state & RTS_INTERFACE)))
5424314Ssklower 				rt->rt_timer += TIMER_RATE;
5524314Ssklower 			if (rt->rt_timer >= EXPIRE_TIME)
5624314Ssklower 				rt->rt_metric = HOPCNT_INFINITY;
5724314Ssklower 			if (rt->rt_timer >= GARBAGE_TIME) {
5824314Ssklower 				rt = rt->rt_back;
5924314Ssklower 				/* Perhaps we should send a REQUEST for this route? */
6024314Ssklower 				rtdelete(rt->rt_forw);
6124314Ssklower 				continue;
6224314Ssklower 			}
6324314Ssklower 			if (rt->rt_state & RTS_CHANGED) {
6424314Ssklower 				rt->rt_state &= ~RTS_CHANGED;
6524314Ssklower 				/* don't send extraneous packets */
6624314Ssklower 				if (!supplier || timetobroadcast)
6724314Ssklower 					continue;
6824314Ssklower 				msg->rip_cmd = htons(RIPCMD_RESPONSE);
6926171Ssklower 				msg->rip_nets[0].rip_dst =
7026171Ssklower 					(satons_addr(rt->rt_dst)).x_net;
7124314Ssklower 				msg->rip_nets[0].rip_metric =
7224314Ssklower 				   	htons(min(rt->rt_metric+1, HOPCNT_INFINITY));
7346705Sbostic 				toall(sndmsg);
7424314Ssklower 			}
7524314Ssklower 		}
7624314Ssklower 	}
7724314Ssklower 	if (doinghost) {
7824314Ssklower 		doinghost = 0;
7924314Ssklower 		base = nethash;
8024314Ssklower 		goto again;
8124314Ssklower 	}
8224314Ssklower 	if (timetobroadcast)
8324314Ssklower 		toall(supply);
8424314Ssklower 	alarm(TIMER_RATE);
8524314Ssklower }
8624314Ssklower 
8724314Ssklower /*
8824314Ssklower  * On hangup, let everyone know we're going away.
8924314Ssklower  */
9046705Sbostic void
hup()9124314Ssklower hup()
9224314Ssklower {
9324314Ssklower 	register struct rthash *rh;
9424314Ssklower 	register struct rt_entry *rt;
9524314Ssklower 	struct rthash *base = hosthash;
9624314Ssklower 	int doinghost = 1;
9724314Ssklower 
9824314Ssklower 	if (supplier) {
9924314Ssklower again:
10024314Ssklower 		for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) {
10124314Ssklower 			rt = rh->rt_forw;
10224314Ssklower 			for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw)
10324314Ssklower 				rt->rt_metric = HOPCNT_INFINITY;
10424314Ssklower 		}
10524314Ssklower 		if (doinghost) {
10624314Ssklower 			doinghost = 0;
10724314Ssklower 			base = nethash;
10824314Ssklower 			goto again;
10924314Ssklower 		}
11024314Ssklower 		toall(supply);
11124314Ssklower 	}
11224314Ssklower 	exit(1);
11324314Ssklower }
114