timer.c revision 11820
111820Sjulian/*
211820Sjulian * Copyright (c) 1985, 1993
311820Sjulian *	The Regents of the University of California.  All rights reserved.
411820Sjulian *
511820Sjulian * Copyright (c) 1995 John Hay.  All rights reserved.
611820Sjulian *
711820Sjulian * This file includes significant work done at Cornell University by
811820Sjulian * Bill Nesheim.  That work included by permission.
911820Sjulian *
1011820Sjulian * Redistribution and use in source and binary forms, with or without
1111820Sjulian * modification, are permitted provided that the following conditions
1211820Sjulian * are met:
1311820Sjulian * 1. Redistributions of source code must retain the above copyright
1411820Sjulian *    notice, this list of conditions and the following disclaimer.
1511820Sjulian * 2. Redistributions in binary form must reproduce the above copyright
1611820Sjulian *    notice, this list of conditions and the following disclaimer in the
1711820Sjulian *    documentation and/or other materials provided with the distribution.
1811820Sjulian * 3. All advertising materials mentioning features or use of this software
1911820Sjulian *    must display the following acknowledgement:
2011820Sjulian *	This product includes software developed by the University of
2111820Sjulian *	California, Berkeley and its contributors.
2211820Sjulian * 4. Neither the name of the University nor the names of its contributors
2311820Sjulian *    may be used to endorse or promote products derived from this software
2411820Sjulian *    without specific prior written permission.
2511820Sjulian *
2611820Sjulian * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2711820Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2811820Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2911820Sjulian * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
3011820Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3111820Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3211820Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3311820Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3411820Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3511820Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3611820Sjulian * SUCH DAMAGE.
3711820Sjulian *
3811820Sjulian *	$Id: timer.c,v 1.8 1995/10/11 18:57:32 jhay Exp $
3911820Sjulian */
4011820Sjulian
4111820Sjulian#ifndef lint
4211820Sjulianstatic char sccsid[] = "@(#)timer.c	8.1 (Berkeley) 6/5/93";
4311820Sjulian#endif /* not lint */
4411820Sjulian
4511820Sjulian/*
4611820Sjulian * Routing Table Management Daemon
4711820Sjulian */
4811820Sjulian#include "defs.h"
4911820Sjulian#include <unistd.h>
5011820Sjulian#include <stdlib.h>
5111820Sjulian
5211820Sjulianint	timeval = -TIMER_RATE;
5311820Sjulian
5411820Sjulian/*
5511820Sjulian * Timer routine.  Performs routing information supply
5611820Sjulian * duties and manages timers on routing and SAP table entries.
5711820Sjulian */
5811820Sjulianvoid
5911820Sjuliantimer()
6011820Sjulian{
6111820Sjulian	register struct rthash *rh;
6211820Sjulian	register struct rt_entry *rt;
6311820Sjulian	struct rthash *base = hosthash;
6411820Sjulian	register struct sap_hash *sh;
6511820Sjulian	register struct sap_entry *sap;
6611820Sjulian	struct sap_hash *sap_base = sap_head;
6711820Sjulian	int doinghost = 1, timetobroadcast, ripbroadcast, sapbroadcast;
6811820Sjulian
6911820Sjulian	timeval += TIMER_RATE;
7011820Sjulian	if (lookforinterfaces && (timeval % CHECK_INTERVAL) == 0)
7111820Sjulian		ifinit();
7211820Sjulian	timetobroadcast = supplier && (timeval % SUPPLY_INTERVAL) == 0;
7311820Sjulian	ripbroadcast = supplier && timetobroadcast &&
7411820Sjulian			(timeval % RIP_INTERVAL) == 0;
7511820Sjulian	sapbroadcast = timetobroadcast && dosap && !ripbroadcast;
7611820Sjulian
7711820Sjulianagain:
7811820Sjulian	for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) {
7911820Sjulian		rt = rh->rt_forw;
8011820Sjulian		for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
8111820Sjulian			if (rt->rt_clone) {
8211820Sjulian				struct rt_entry *trt, *prt;
8311820Sjulian				/*
8411820Sjulian				 * If a clone expire free it and mark the
8511820Sjulian				 * main route RTS_CHANGED.
8611820Sjulian				 */
8711820Sjulian				prt = rt;
8811820Sjulian				trt = rt->rt_clone;
8911820Sjulian				while (trt) {
9011820Sjulian					trt->rt_timer += TIMER_RATE;
9111820Sjulian					if (trt->rt_timer >= EXPIRE_TIME) {
9211820Sjulian						prt->rt_clone = trt->rt_clone;
9311820Sjulian						free((char *)trt);
9411820Sjulian						trt = prt->rt_clone;
9511820Sjulian						rt->rt_state |= RTS_CHANGED;
9611820Sjulian					} else {
9711820Sjulian						prt = trt;
9811820Sjulian						trt = prt->rt_clone;
9911820Sjulian					}
10011820Sjulian				}
10111820Sjulian			}
10211820Sjulian			/*
10311820Sjulian			 * We don't advance time on a routing entry for
10411820Sjulian			 * a passive gateway or that for our only interface.
10511820Sjulian			 * The latter is excused because we don't act as
10611820Sjulian			 * a routing information supplier and hence would
10711820Sjulian			 * time it out.  This is fair as if it's down
10811820Sjulian			 * we're cut off from the world anyway and it's
10911820Sjulian			 * not likely we'll grow any new hardware in
11011820Sjulian			 * the mean time.
11111820Sjulian			 */
11211820Sjulian			if (!(rt->rt_state & RTS_PASSIVE) &&
11311820Sjulian			    !(rt->rt_state & RTS_INTERFACE))
11411820Sjulian				rt->rt_timer += TIMER_RATE;
11511820Sjulian			if (rt->rt_timer >= EXPIRE_TIME)
11611820Sjulian				rt->rt_metric = HOPCNT_INFINITY;
11711820Sjulian			if (rt->rt_timer >= GARBAGE_TIME) {
11811820Sjulian				rt = rt->rt_back;
11911820Sjulian				/* Perhaps we should send a REQUEST for this route? */
12011820Sjulian				rtdelete(rt->rt_forw);
12111820Sjulian				continue;
12211820Sjulian			}
12311820Sjulian			if (rt->rt_state & RTS_CHANGED) {
12411820Sjulian				rt->rt_state &= ~RTS_CHANGED;
12511820Sjulian				/* don't send extraneous packets */
12611820Sjulian				if (!supplier || ripbroadcast)
12711820Sjulian					continue;
12811820Sjulian				msg->rip_cmd = htons(RIPCMD_RESPONSE);
12911820Sjulian				msg->rip_nets[0].rip_dst =
13011820Sjulian					(satoipx_addr(rt->rt_dst)).x_net;
13111820Sjulian				msg->rip_nets[0].rip_metric =
13211820Sjulian				   	htons(min(rt->rt_metric+1, HOPCNT_INFINITY));
13311820Sjulian				msg->rip_nets[0].rip_ticks =
13411820Sjulian					htons(rt->rt_ticks + 1);
13511820Sjulian				toall(sndmsg, rt);
13611820Sjulian			}
13711820Sjulian		}
13811820Sjulian	}
13911820Sjulian	if (doinghost) {
14011820Sjulian		doinghost = 0;
14111820Sjulian		base = nethash;
14211820Sjulian		goto again;
14311820Sjulian	}
14411820Sjulian	if (ripbroadcast)
14511820Sjulian		toall(supply, NULL);
14611820Sjulian
14711820Sjulian	/*
14811820Sjulian	 * Now do the SAP stuff.
14911820Sjulian	 */
15011820Sjulian	for (sh = sap_base; sh < &sap_base[SAPHASHSIZ]; sh++) {
15111820Sjulian		sap = sh->forw;
15211820Sjulian		for (; sap != (struct sap_entry *)sh; sap = sap->forw) {
15311820Sjulian			if (sap->clone) {
15411820Sjulian				struct sap_entry *tsap, *psap;
15511820Sjulian				/*
15611820Sjulian				 * If a clone expire free it and mark the
15711820Sjulian				 * main sap entry RTS_CHANGED.
15811820Sjulian				 */
15911820Sjulian				psap = sap;
16011820Sjulian				tsap = sap->clone;
16111820Sjulian				while (tsap) {
16211820Sjulian					tsap->timer += TIMER_RATE;
16311820Sjulian					if (tsap->timer >= EXPIRE_TIME) {
16411820Sjulian						psap->clone = tsap->clone;
16511820Sjulian						free((char *)tsap);
16611820Sjulian						tsap = psap->clone;
16711820Sjulian						sap->state |= RTS_CHANGED;
16811820Sjulian					} else {
16911820Sjulian						psap = tsap;
17011820Sjulian						tsap = psap->clone;
17111820Sjulian					}
17211820Sjulian				}
17311820Sjulian			}
17411820Sjulian			sap->timer += TIMER_RATE;
17511820Sjulian			if (sap->timer >= EXPIRE_TIME)
17611820Sjulian				sap->metric = HOPCNT_INFINITY;
17711820Sjulian			if (sap->timer >= GARBAGE_TIME) {
17811820Sjulian				sap = sap->back;
17911820Sjulian				/* Perhaps we should send a REQUEST for this route? */
18011820Sjulian				sap_delete(sap->forw);
18111820Sjulian				continue;
18211820Sjulian			}
18311820Sjulian			/*
18411820Sjulian			 * XXX sap_sndmsg on RTS_CHANGED
18511820Sjulian			 */
18611820Sjulian		}
18711820Sjulian	}
18811820Sjulian	if (sapbroadcast)
18911820Sjulian		sap_supply_toall();
19011820Sjulian	if (ftrace && sapbroadcast)
19111820Sjulian		dumpsaptable(ftrace, sap_head);
19211820Sjulian	alarm(TIMER_RATE);
19311820Sjulian}
19411820Sjulian
19511820Sjulian/*
19611820Sjulian * On hangup, let everyone know we're going away.
19711820Sjulian */
19811820Sjulianvoid
19911820Sjulianhup()
20011820Sjulian{
20111820Sjulian	register struct rthash *rh;
20211820Sjulian	register struct rt_entry *rt;
20311820Sjulian	struct rthash *base = hosthash;
20411820Sjulian	register struct sap_hash *sh;
20511820Sjulian	register struct sap_entry *sap;
20611820Sjulian	int doinghost = 1;
20711820Sjulian
20811820Sjulian	if (supplier) {
20911820Sjulianagain:
21011820Sjulian		for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) {
21111820Sjulian			rt = rh->rt_forw;
21211820Sjulian			for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw)
21311820Sjulian				rt->rt_metric = HOPCNT_INFINITY;
21411820Sjulian		}
21511820Sjulian		if (doinghost) {
21611820Sjulian			doinghost = 0;
21711820Sjulian			base = nethash;
21811820Sjulian			goto again;
21911820Sjulian		}
22011820Sjulian		toall(supply, NULL);
22111820Sjulian
22211820Sjulian		/*
22311820Sjulian		 * Now for SAP.
22411820Sjulian		 */
22511820Sjulian		for (sh = sap_head; sh < &sap_head[SAPHASHSIZ]; sh++) {
22611820Sjulian			sap = sh->forw;
22711820Sjulian			for (; sap != (struct sap_entry *)sh; sap = sap->forw)
22811820Sjulian				sap->sap.hops = htons(HOPCNT_INFINITY);
22911820Sjulian		}
23011820Sjulian		if (dosap)
23111820Sjulian			sap_supply_toall();
23211820Sjulian	}
23311820Sjulian	exit(1);
23411820Sjulian}
235