xref: /csrg-svn/sbin/XNSrouted/timer.c (revision 24314)
1*24314Ssklower #ifndef lint
2*24314Ssklower static char rcsid[] = "$Header$";
3*24314Ssklower #endif
4*24314Ssklower 
5*24314Ssklower /*
6*24314Ssklower  * Routing Table Management Daemon
7*24314Ssklower  */
8*24314Ssklower #include "defs.h"
9*24314Ssklower 
10*24314Ssklower int	timeval = -TIMER_RATE;
11*24314Ssklower 
12*24314Ssklower /*
13*24314Ssklower  * Timer routine.  Performs routing information supply
14*24314Ssklower  * duties and manages timers on routing table entries.
15*24314Ssklower  */
16*24314Ssklower timer()
17*24314Ssklower {
18*24314Ssklower 	register struct rthash *rh;
19*24314Ssklower 	register struct rt_entry *rt;
20*24314Ssklower 	struct rthash *base = hosthash;
21*24314Ssklower 	int doinghost = 1, timetobroadcast;
22*24314Ssklower 
23*24314Ssklower 	timeval += TIMER_RATE;
24*24314Ssklower 	if (lookforinterfaces && (timeval % CHECK_INTERVAL) == 0)
25*24314Ssklower 		ifinit();
26*24314Ssklower 	timetobroadcast = supplier && (timeval % SUPPLY_INTERVAL) == 0;
27*24314Ssklower again:
28*24314Ssklower 	for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) {
29*24314Ssklower 		rt = rh->rt_forw;
30*24314Ssklower 		for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
31*24314Ssklower 			/*
32*24314Ssklower 			 * We don't advance time on a routing entry for
33*24314Ssklower 			 * a passive gateway or that for our only interface.
34*24314Ssklower 			 * The latter is excused because we don't act as
35*24314Ssklower 			 * a routing information supplier and hence would
36*24314Ssklower 			 * time it out.  This is fair as if it's down
37*24314Ssklower 			 * we're cut off from the world anyway and it's
38*24314Ssklower 			 * not likely we'll grow any new hardware in
39*24314Ssklower 			 * the mean time.
40*24314Ssklower 			 */
41*24314Ssklower 			if (!(rt->rt_state & RTS_PASSIVE) &&
42*24314Ssklower 			    (supplier || !(rt->rt_state & RTS_INTERFACE)))
43*24314Ssklower 				rt->rt_timer += TIMER_RATE;
44*24314Ssklower 			if (rt->rt_timer >= EXPIRE_TIME)
45*24314Ssklower 				rt->rt_metric = HOPCNT_INFINITY;
46*24314Ssklower 			if (rt->rt_timer >= GARBAGE_TIME) {
47*24314Ssklower 				rt = rt->rt_back;
48*24314Ssklower 				/* Perhaps we should send a REQUEST for this route? */
49*24314Ssklower 				rtdelete(rt->rt_forw);
50*24314Ssklower 				continue;
51*24314Ssklower 			}
52*24314Ssklower 			if (rt->rt_state & RTS_CHANGED) {
53*24314Ssklower 				rt->rt_state &= ~RTS_CHANGED;
54*24314Ssklower 				/* don't send extraneous packets */
55*24314Ssklower 				if (!supplier || timetobroadcast)
56*24314Ssklower 					continue;
57*24314Ssklower 				msg->rip_cmd = htons(RIPCMD_RESPONSE);
58*24314Ssklower 				xnnet(msg->rip_nets[0].rip_dst) =
59*24314Ssklower 					htonl(xnnet(((struct sockaddr_xn *)&rt->rt_dst)->sxn_addr.xn_net));
60*24314Ssklower 				msg->rip_nets[0].rip_metric =
61*24314Ssklower 				   	htons(min(rt->rt_metric+1, HOPCNT_INFINITY));
62*24314Ssklower 				toall(sendmsg);
63*24314Ssklower 			}
64*24314Ssklower 		}
65*24314Ssklower 	}
66*24314Ssklower 	if (doinghost) {
67*24314Ssklower 		doinghost = 0;
68*24314Ssklower 		base = nethash;
69*24314Ssklower 		goto again;
70*24314Ssklower 	}
71*24314Ssklower 	if (timetobroadcast)
72*24314Ssklower 		toall(supply);
73*24314Ssklower 	alarm(TIMER_RATE);
74*24314Ssklower }
75*24314Ssklower 
76*24314Ssklower /*
77*24314Ssklower  * On hangup, let everyone know we're going away.
78*24314Ssklower  */
79*24314Ssklower hup()
80*24314Ssklower {
81*24314Ssklower 	register struct rthash *rh;
82*24314Ssklower 	register struct rt_entry *rt;
83*24314Ssklower 	struct rthash *base = hosthash;
84*24314Ssklower 	int doinghost = 1;
85*24314Ssklower 
86*24314Ssklower 	if (supplier) {
87*24314Ssklower again:
88*24314Ssklower 		for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) {
89*24314Ssklower 			rt = rh->rt_forw;
90*24314Ssklower 			for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw)
91*24314Ssklower 				rt->rt_metric = HOPCNT_INFINITY;
92*24314Ssklower 		}
93*24314Ssklower 		if (doinghost) {
94*24314Ssklower 			doinghost = 0;
95*24314Ssklower 			base = nethash;
96*24314Ssklower 			goto again;
97*24314Ssklower 		}
98*24314Ssklower 		toall(supply);
99*24314Ssklower 	}
100*24314Ssklower 	exit(1);
101*24314Ssklower }
102