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