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