/* * Copyright (c) 1985 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * * Includes material written at Cornell University by Bill Nesheim, * by permission of the author. */ #ifndef lint static char sccsid[] = "@(#)timer.c 5.4 (Berkeley) 2/14/86"; #endif not lint /* * Routing Table Management Daemon */ #include "defs.h" int timeval = -TIMER_RATE; /* * Timer routine. Performs routing information supply * duties and manages timers on routing table entries. */ timer() { register struct rthash *rh; register struct rt_entry *rt; struct rthash *base = hosthash; int doinghost = 1, timetobroadcast; timeval += TIMER_RATE; if (lookforinterfaces && (timeval % CHECK_INTERVAL) == 0) ifinit(); timetobroadcast = supplier && (timeval % SUPPLY_INTERVAL) == 0; again: for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) { rt = rh->rt_forw; for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { /* * We don't advance time on a routing entry for * a passive gateway or that for our only interface. * The latter is excused because we don't act as * a routing information supplier and hence would * time it out. This is fair as if it's down * we're cut off from the world anyway and it's * not likely we'll grow any new hardware in * the mean time. */ if (!(rt->rt_state & RTS_PASSIVE) && (supplier || !(rt->rt_state & RTS_INTERFACE))) rt->rt_timer += TIMER_RATE; if (rt->rt_timer >= EXPIRE_TIME) rt->rt_metric = HOPCNT_INFINITY; if (rt->rt_timer >= GARBAGE_TIME) { rt = rt->rt_back; /* Perhaps we should send a REQUEST for this route? */ rtdelete(rt->rt_forw); continue; } if (rt->rt_state & RTS_CHANGED) { rt->rt_state &= ~RTS_CHANGED; /* don't send extraneous packets */ if (!supplier || timetobroadcast) continue; msg->rip_cmd = htons(RIPCMD_RESPONSE); msg->rip_nets[0].rip_dst = (satons_addr(rt->rt_dst)).x_net; msg->rip_nets[0].rip_metric = htons(min(rt->rt_metric+1, HOPCNT_INFINITY)); toall(sendmsg); } } } if (doinghost) { doinghost = 0; base = nethash; goto again; } if (timetobroadcast) toall(supply); alarm(TIMER_RATE); } /* * On hangup, let everyone know we're going away. */ hup() { register struct rthash *rh; register struct rt_entry *rt; struct rthash *base = hosthash; int doinghost = 1; if (supplier) { again: for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) { rt = rh->rt_forw; for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) rt->rt_metric = HOPCNT_INFINITY; } if (doinghost) { doinghost = 0; base = nethash; goto again; } toall(supply); } exit(1); }