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