timer.c revision 27244
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 * 3827244Sjhay * $Id: timer.c,v 1.3 1997/02/22 16:01:03 peter 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 register struct sap_hash *sh; 6411820Sjulian register struct sap_entry *sap; 6511820Sjulian struct sap_hash *sap_base = sap_head; 6627244Sjhay int timetobroadcast, ripbroadcast, sapbroadcast; 6711820Sjulian 6811820Sjulian timeval += TIMER_RATE; 6911820Sjulian if (lookforinterfaces && (timeval % CHECK_INTERVAL) == 0) 7011820Sjulian ifinit(); 7111820Sjulian timetobroadcast = supplier && (timeval % SUPPLY_INTERVAL) == 0; 7211820Sjulian ripbroadcast = supplier && timetobroadcast && 7311820Sjulian (timeval % RIP_INTERVAL) == 0; 7411820Sjulian sapbroadcast = timetobroadcast && dosap && !ripbroadcast; 7511820Sjulian 7627244Sjhay for (rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++) { 7711820Sjulian rt = rh->rt_forw; 7811820Sjulian for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { 7911820Sjulian if (rt->rt_clone) { 8011820Sjulian struct rt_entry *trt, *prt; 8111820Sjulian /* 8211820Sjulian * If a clone expire free it and mark the 8311820Sjulian * main route RTS_CHANGED. 8411820Sjulian */ 8511820Sjulian prt = rt; 8611820Sjulian trt = rt->rt_clone; 8711820Sjulian while (trt) { 8811820Sjulian trt->rt_timer += TIMER_RATE; 8911820Sjulian if (trt->rt_timer >= EXPIRE_TIME) { 9011820Sjulian prt->rt_clone = trt->rt_clone; 9111820Sjulian free((char *)trt); 9211820Sjulian trt = prt->rt_clone; 9311820Sjulian rt->rt_state |= RTS_CHANGED; 9411820Sjulian } else { 9511820Sjulian prt = trt; 9611820Sjulian trt = prt->rt_clone; 9711820Sjulian } 9811820Sjulian } 9911820Sjulian } 10011820Sjulian /* 10111820Sjulian * We don't advance time on a routing entry for 10211820Sjulian * a passive gateway or that for our only interface. 10311820Sjulian * The latter is excused because we don't act as 10411820Sjulian * a routing information supplier and hence would 10511820Sjulian * time it out. This is fair as if it's down 10611820Sjulian * we're cut off from the world anyway and it's 10711820Sjulian * not likely we'll grow any new hardware in 10811820Sjulian * the mean time. 10911820Sjulian */ 11011820Sjulian if (!(rt->rt_state & RTS_PASSIVE) && 11111820Sjulian !(rt->rt_state & RTS_INTERFACE)) 11211820Sjulian rt->rt_timer += TIMER_RATE; 11327244Sjhay if (rt->rt_timer >= EXPIRE_TIME) { 11411820Sjulian rt->rt_metric = HOPCNT_INFINITY; 11527244Sjhay rt->rt_state |= RTS_CHANGED; 11627244Sjhay } 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; 12827244Sjhay if ((rt->rt_metric + 1) == HOPCNT_INFINITY) 12927244Sjhay continue; 13011820Sjulian msg->rip_cmd = htons(RIPCMD_RESPONSE); 13111820Sjulian msg->rip_nets[0].rip_dst = 13211820Sjulian (satoipx_addr(rt->rt_dst)).x_net; 13311820Sjulian msg->rip_nets[0].rip_metric = 13411820Sjulian htons(min(rt->rt_metric+1, HOPCNT_INFINITY)); 13511820Sjulian msg->rip_nets[0].rip_ticks = 13611820Sjulian htons(rt->rt_ticks + 1); 13727244Sjhay toall(sndmsg, rt, 0); 13811820Sjulian } 13911820Sjulian } 14011820Sjulian } 14111820Sjulian if (ripbroadcast) 14227244Sjhay toall(supply, NULL, 0); 14311820Sjulian 14411820Sjulian /* 14511820Sjulian * Now do the SAP stuff. 14611820Sjulian */ 14711820Sjulian for (sh = sap_base; sh < &sap_base[SAPHASHSIZ]; sh++) { 14811820Sjulian sap = sh->forw; 14911820Sjulian for (; sap != (struct sap_entry *)sh; sap = sap->forw) { 15011820Sjulian if (sap->clone) { 15111820Sjulian struct sap_entry *tsap, *psap; 15211820Sjulian /* 15311820Sjulian * If a clone expire free it and mark the 15411820Sjulian * main sap entry RTS_CHANGED. 15511820Sjulian */ 15611820Sjulian psap = sap; 15711820Sjulian tsap = sap->clone; 15811820Sjulian while (tsap) { 15911820Sjulian tsap->timer += TIMER_RATE; 16011820Sjulian if (tsap->timer >= EXPIRE_TIME) { 16111820Sjulian psap->clone = tsap->clone; 16211820Sjulian free((char *)tsap); 16311820Sjulian tsap = psap->clone; 16411820Sjulian sap->state |= RTS_CHANGED; 16511820Sjulian } else { 16611820Sjulian psap = tsap; 16711820Sjulian tsap = psap->clone; 16811820Sjulian } 16911820Sjulian } 17011820Sjulian } 17111820Sjulian sap->timer += TIMER_RATE; 17227244Sjhay if (sap->timer >= EXPIRE_TIME) { 17327244Sjhay sap->sap.hops = htons(HOPCNT_INFINITY); 17427244Sjhay sap->state |= RTS_CHANGED; 17527244Sjhay } 17611820Sjulian if (sap->timer >= GARBAGE_TIME) { 17711820Sjulian sap = sap->back; 17811820Sjulian /* Perhaps we should send a REQUEST for this route? */ 17911820Sjulian sap_delete(sap->forw); 18011820Sjulian continue; 18111820Sjulian } 18211820Sjulian /* 18311820Sjulian * XXX sap_sndmsg on RTS_CHANGED 18411820Sjulian */ 18527244Sjhay if (sap->state & RTS_CHANGED) { 18627244Sjhay sap->state &= ~RTS_CHANGED; 18727244Sjhay#ifdef notyet 18827244Sjhay /* don't send extraneous packets */ 18927244Sjhay if (!supplier || sapbroadcast) 19027244Sjhay continue; 19127244Sjhay if ((ntohs(sap->sap.hops) + 1) == HOPCNT_INFINITY) 19227244Sjhay continue; 19327244Sjhay sap_msg->sap_cmd = htons(SAP_RESP); 19427244Sjhay sap_msg->sap[0] = sap->sap; 19527244Sjhay sap_msg->sap[0].hops = 19627244Sjhay htons(min(sap->sap.hops+1, HOPCNT_INFINITY)); 19727244Sjhay toall(sapsndmsg, rt, 0); 19827244Sjhay#endif 19927244Sjhay } 20011820Sjulian } 20111820Sjulian } 20211820Sjulian if (sapbroadcast) 20327244Sjhay sap_supply_toall(0); 20411820Sjulian if (ftrace && sapbroadcast) 20511820Sjulian dumpsaptable(ftrace, sap_head); 20611820Sjulian} 20711820Sjulian 20811820Sjulian/* 20911820Sjulian * On hangup, let everyone know we're going away. 21011820Sjulian */ 21111820Sjulianvoid 21211820Sjulianhup() 21311820Sjulian{ 21411820Sjulian register struct rthash *rh; 21511820Sjulian register struct rt_entry *rt; 21611820Sjulian register struct sap_hash *sh; 21711820Sjulian register struct sap_entry *sap; 21811820Sjulian 21911820Sjulian if (supplier) { 22027244Sjhay for (rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++) { 22111820Sjulian rt = rh->rt_forw; 22211820Sjulian for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) 22311820Sjulian rt->rt_metric = HOPCNT_INFINITY; 22411820Sjulian } 22527244Sjhay toall(supply, NULL, 0); 22611820Sjulian 22711820Sjulian /* 22811820Sjulian * Now for SAP. 22911820Sjulian */ 23011820Sjulian for (sh = sap_head; sh < &sap_head[SAPHASHSIZ]; sh++) { 23111820Sjulian sap = sh->forw; 23211820Sjulian for (; sap != (struct sap_entry *)sh; sap = sap->forw) 23311820Sjulian sap->sap.hops = htons(HOPCNT_INFINITY); 23411820Sjulian } 23511820Sjulian if (dosap) 23627244Sjhay sap_supply_toall(0); 23711820Sjulian } 23811820Sjulian exit(1); 23911820Sjulian} 240