-/*
- * Timer routine:
- *
- * o handle timers on table entries,
- * o invalidate entries which haven't been updated in a while,
- * o delete entries which are too old,
- * o retry ioctl's which weren't successful the first
- * time due to the kernel entry being busy
- * o if we're an internetwork router, supply routing updates
- * periodically
- */
-timer()
-{
- register struct rt_hash *rh;
- register struct rt_entry *rt;
- struct rt_hash *base = hosthash;
- int doinghost = 1;
-
- if (trace)
- printf(">>> time %d >>>\n", timeval);
-again:
- for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) {
- rt = rh->rt_forw;
- for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
-
- /*
- * If the host is indicated to be
- * "silent" (i.e. it's one we got
- * from the initialization file),
- * don't time out it's entry.
- */
- if ((rt->rt_flags & RTF_SILENT) == 0)
- rt->rt_timer += TIMER_RATE;
- log("", rt);
-
- /*
- * If the entry should be deleted
- * attempt to do so and reclaim space.
- */
- if (rt->rt_timer >= GARBAGE_TIME ||
- (rt->rt_flags & RTF_DELRT)) {
- rt = rt->rt_forw;
- rtdelete(rt->rt_back);
- rt = rt->rt_back;
- continue;
- }
-
- /*
- * If we haven't heard from the router
- * in a long time indicate the route is
- * hard to reach.
- */
- if (rt->rt_timer >= EXPIRE_TIME)
- rt->rt_metric = HOPCNT_INFINITY;
- if (rt->rt_flags & RTF_CHGRT)
- if (!ioctl(s, SIOCCHGRT,(char *)&rt->rt_hash) ||
- --rt->rt_retry == 0)
- rt->rt_flags &= ~RTF_CHGRT;
-
- /*
- * Try to add the route to the kernel tables.
- * If this fails because the entry already exists
- * (perhaps because someone manually added it)
- * change the add to a change. If the operation
- * fails otherwise (likely because the entry is
- * in use), retry the operation a few more times.
- */
- if (rt->rt_flags & RTF_ADDRT) {
- if (!ioctl(s, SIOCADDRT,(char *)&rt->rt_hash)) {
- if (errno == EEXIST) {
- rt->rt_flags &= ~RTF_ADDRT;
- rt->rt_flags |= RTF_CHGRT;
- rt->rt_retry =
- (EXPIRE_TIME/TIMER_RATE);
- continue;
- }
- if (--rt->rt_retry)
- continue;
- }
- rt->rt_flags &= ~RTF_ADDRT;
- }
- }
- }
- if (doinghost) {
- doinghost = 0;
- base = nethash;
- goto again;
- }
- timeval += TIMER_RATE;
- if (lookforinterfaces && (timeval % CHECK_INTERVAL) == 0)
- getinterfaces();
- if (supplier && (timeval % SUPPLY_INTERVAL) == 0)
- supplyall();
- if (trace)
- printf("<<< time %d <<<\n", timeval);
- alarm(TIMER_RATE);
-}