DIRECTORY BasicTime USING [GMT, Now, Period, Update], Rope USING [Cat, Equal, Length, Match, ROPE], IPDefs USING [Address], IPNameCache, IPNameSupport USING [MakeAddressInList, MakeRopeInList]; IPNameCacheImpl: CEDAR MONITOR IMPORTS BasicTime, Rope, IPNameSupport EXPORTS IPNameCache = BEGIN OPEN IPNameCache; ROPE: TYPE = Rope.ROPE; ttlDefault: INT = 3333; ZapWholeCache: PUBLIC ENTRY PROC = { names _ NIL; aliases _ NIL; mxList _ NIL; bogusAddresses _ NIL; bogusNames _ NIL; addresses _ NIL; downNames _ NIL; downAddresses _ NIL; downServers _ NIL; zones _ NIL; histograms _ NIL; }; names: LIST OF NameEntry _ NIL; GetNames: PUBLIC ENTRY PROC RETURNS [LIST OF NameEntry] = { RETURN[names]; }; NameLookup: PUBLIC ENTRY PROC [name: ROPE] RETURNS [entry: NameEntry] = {RETURN[NameLookupInternal[name]]}; NameLookupInternal: PROC [name: ROPE] RETURNS [entry: NameEntry] = { FOR list: LIST OF NameEntry _ names, list.rest UNTIL list = NIL DO entry _ list.first; IF Rope.Equal[entry.name, name, FALSE] THEN { entry.referenced _ BasicTime.Now[]; RETURN; }; ENDLOOP; RETURN[NIL]; }; UpdateName: PUBLIC ENTRY PROC [ name: ROPE, source: IPDefs.Address, ttl: INT, authoritative: BOOL] RETURNS [entry: NameEntry] = { entry _ NameLookupInternal[name]; IF entry # NIL THEN { now: BasicTime.GMT _ BasicTime.Now[]; thisTtl: INT = BasicTime.Period[from: now, to: entry.expires]; IF thisTtl < -10 THEN entry.authoritative _ FALSE; IF entry.authoritative AND ~authoritative THEN RETURN[NIL]; IF ~entry.authoritative AND authoritative THEN { entry.addresses _ NIL; }; entry.source _ source; entry.loaded _ now; entry.referenced _ now; entry.expires _ BasicTime.Update[now, ttl]; entry.ttl _ ttl; entry.authoritative _ authoritative; RETURN[entry]; }; entry _ MakeNameEntry[source, ttl, authoritative]; entry.name _ name; RETURN[entry]; }; MakeNameEntry: PROC [ source: IPDefs.Address, ttl: INT, authoritative: BOOL] RETURNS [entry: NameEntry] = { now: BasicTime.GMT _ BasicTime.Now[]; expires: INT _ ttl; IF expires = 0 THEN expires _ ttlDefault; entry _ NEW[NameRecord]; entry^ _ [ loaded: now, referenced: now, expires: BasicTime.Update[now, expires], ttl: ttl, source: source, authoritative: authoritative ]; names _ CONS[entry, names]; }; AddAddressToName: PUBLIC ENTRY PROC [entry: NameEntry, address: IPDefs.Address] = { entry.addresses _ IPNameSupport.MakeAddressInList[entry.addresses, address]; }; aliases: LIST OF AliasEntry _ NIL; GetAliases: PUBLIC ENTRY PROC RETURNS [LIST OF AliasEntry] = { RETURN[aliases]; }; AliasLookup: PUBLIC ENTRY PROC [alias: ROPE] RETURNS [entry: AliasEntry] = {RETURN[AliasLookupInternal[alias]]}; AliasLookupInternal: PROC [alias: ROPE] RETURNS [entry: AliasEntry] = { FOR list: LIST OF AliasEntry _ aliases, list.rest UNTIL list = NIL DO entry _ list.first; IF Rope.Equal[entry.alias, alias, FALSE] THEN { entry.referenced _ BasicTime.Now[]; RETURN; }; ENDLOOP; RETURN[NIL]; }; UpdateAlias: PUBLIC ENTRY PROC [ alias: ROPE, source: IPDefs.Address, ttl: INT, authoritative: BOOL] RETURNS [entry: AliasEntry] = { entry _ AliasLookupInternal[alias]; IF entry # NIL THEN { now: BasicTime.GMT _ BasicTime.Now[]; thisTtl: INT = BasicTime.Period[from: now, to: entry.expires]; IF thisTtl < -10 THEN entry.authoritative _ FALSE; IF entry.authoritative AND ~authoritative THEN RETURN[NIL]; IF ~entry.authoritative AND authoritative THEN { entry.name _ NIL; }; entry.source _ source; entry.loaded _ now; entry.referenced _ now; entry.expires _ BasicTime.Update[now, ttl]; entry.ttl _ ttl; entry.authoritative _ authoritative; RETURN[entry]; }; entry _ MakeAliasEntry[source, ttl, authoritative]; entry.alias _ alias; RETURN[entry]; }; MakeAliasEntry: PROC [ source: IPDefs.Address, ttl: INT, authoritative: BOOL] RETURNS [entry: AliasEntry] = { now: BasicTime.GMT _ BasicTime.Now[]; expires: INT _ ttl; IF expires = 0 THEN expires _ ttlDefault; entry _ NEW[AliasRecord]; entry^ _ [ loaded: now, referenced: now, expires: BasicTime.Update[now, expires], ttl: ttl, source: source, authoritative: authoritative ]; aliases _ CONS[entry, aliases]; }; AddNameToAlias: PUBLIC ENTRY PROC [entry: AliasEntry, name: ROPE] = { entry.name _ name; }; mxList: LIST OF MXEntry _ NIL; GetMXList: PUBLIC ENTRY PROC RETURNS [LIST OF MXEntry] = { RETURN[mxList]; }; MXLookup: PUBLIC ENTRY PROC [name: ROPE] RETURNS [entry: MXEntry] = {RETURN[MXLookupInternal[name]]}; MXLookupInternal: PROC [name: ROPE] RETURNS [entry: MXEntry] = { FOR list: LIST OF MXEntry _ mxList, list.rest UNTIL list = NIL DO entry _ list.first; IF Rope.Equal[entry.name, name, FALSE] THEN { entry.referenced _ BasicTime.Now[]; RETURN; }; ENDLOOP; RETURN[NIL]; }; UpdateMX: PUBLIC ENTRY PROC [ name: ROPE, source: IPDefs.Address, ttl: INT, authoritative: BOOL] RETURNS [entry: MXEntry] = { entry _ MXLookupInternal[name]; IF entry # NIL THEN { now: BasicTime.GMT _ BasicTime.Now[]; thisTtl: INT = BasicTime.Period[from: now, to: entry.expires]; IF thisTtl < -10 THEN entry.authoritative _ FALSE; IF entry.authoritative AND ~authoritative THEN RETURN[NIL]; IF ~entry.authoritative AND authoritative THEN { entry.mxHosts _ NIL; }; entry.source _ source; entry.loaded _ now; entry.referenced _ now; entry.expires _ BasicTime.Update[now, ttl]; entry.ttl _ ttl; entry.authoritative _ authoritative; RETURN[entry]; }; entry _ MakeMXEntry[source, ttl, authoritative]; entry.name _ name; RETURN[entry]; }; MakeMXEntry: PROC [ source: IPDefs.Address, ttl: INT, authoritative: BOOL] RETURNS [entry: MXEntry] = { now: BasicTime.GMT _ BasicTime.Now[]; expires: INT _ ttl; IF expires = 0 THEN expires _ ttlDefault; entry _ NEW[MXRecord]; entry^ _ [ loaded: now, referenced: now, expires: BasicTime.Update[now, expires], ttl: ttl, source: source, authoritative: authoritative ]; mxList _ CONS[entry, mxList]; }; AddHostToMX: PUBLIC ENTRY PROC [entry: MXEntry, hostInfo: MXHostInfo] = { IF ~AlreadyInMXList[entry.mxHosts, hostInfo] THEN entry.mxHosts _ CONS[hostInfo, entry.mxHosts]; }; AlreadyInMXList: PROC[mxHosts: LIST OF MXHostInfo, hostInfo: MXHostInfo] RETURNS[BOOL] = { FOR list: LIST OF MXHostInfo _ mxHosts, list.rest UNTIL list = NIL DO IF Rope.Equal[list.first.host, hostInfo.host, FALSE] AND list.first.preference = hostInfo.preference THEN RETURN[TRUE]; ENDLOOP; RETURN[FALSE]; }; bogusNames: LIST OF BogusNameEntry _ NIL; GetBogusNames: PUBLIC ENTRY PROC RETURNS [LIST OF BogusNameEntry] = { RETURN[bogusNames]; }; BogusNameLookup: PUBLIC ENTRY PROC [bogus: ROPE] RETURNS [entry: BogusNameEntry] = {RETURN[BogusNameLookupInternal[bogus]]}; BogusNameLookupInternal: PROC [bogus: ROPE] RETURNS [entry: BogusNameEntry] = { FOR list: LIST OF BogusNameEntry _ bogusNames, list.rest UNTIL list = NIL DO entry _ list.first; IF Rope.Equal[entry.bogus, bogus, FALSE] THEN { entry.referenced _ BasicTime.Now[]; RETURN; }; ENDLOOP; RETURN[NIL]; }; UpdateBogusName: PUBLIC ENTRY PROC [ bogus: ROPE, source: IPDefs.Address, ttl: INT, authoritative: BOOL] RETURNS [entry: BogusNameEntry] = { entry _ BogusNameLookupInternal[bogus]; IF entry # NIL THEN { now: BasicTime.GMT _ BasicTime.Now[]; thisTtl: INT = BasicTime.Period[from: now, to: entry.expires]; IF thisTtl < -10 THEN entry.authoritative _ FALSE; IF entry.authoritative AND ~authoritative THEN RETURN[NIL]; IF ~entry.authoritative AND authoritative THEN { NULL; }; entry.source _ source; entry.loaded _ now; entry.referenced _ now; entry.expires _ BasicTime.Update[now, ttl]; entry.ttl _ ttl; entry.authoritative _ authoritative; RETURN[entry]; }; entry _ MakeBogusName[source, ttl, authoritative]; entry.bogus _ bogus; RETURN[entry]; }; MakeBogusName: PROC [ source: IPDefs.Address, ttl: INT, authoritative: BOOL] RETURNS [entry: BogusNameEntry] = { now: BasicTime.GMT _ BasicTime.Now[]; expires: INT _ ttl; IF expires = 0 THEN expires _ ttlDefault; entry _ NEW[BogusNameRecord]; entry^ _ [ loaded: now, referenced: now, expires: BasicTime.Update[now, expires], ttl: ttl, source: source, authoritative: authoritative ]; bogusNames _ CONS[entry, bogusNames]; }; downNames: LIST OF DownNameEntry _ NIL; GetDownNames: PUBLIC ENTRY PROC RETURNS [LIST OF DownNameEntry] = { RETURN[downNames]; }; DownNameLookup: PUBLIC ENTRY PROC [name: ROPE] RETURNS [entry: DownNameEntry] = { entry _ DownNameLookupInternal[name]; IF entry # NIL THEN { now: BasicTime.GMT _ BasicTime.Now[]; thisTtl: INT = BasicTime.Period[from: now, to: entry.expires]; IF thisTtl < -10 THEN RETURN[NIL];}; -- Don't show expired items RETURN[entry]}; DownNameLookupInternal: PROC [name: ROPE] RETURNS [entry: DownNameEntry] = { FOR list: LIST OF DownNameEntry _ downNames, list.rest UNTIL list = NIL DO entry _ list.first; IF Rope.Equal[entry.name, name, FALSE] THEN { entry.referenced _ BasicTime.Now[]; RETURN; }; ENDLOOP; RETURN[NIL]; }; UpdateDownName: PUBLIC ENTRY PROC [ name: ROPE, ttl: INT] RETURNS [entry: DownNameEntry] = { entry _ DownNameLookupInternal[name]; IF entry # NIL THEN { now: BasicTime.GMT _ BasicTime.Now[]; thisTtl: INT = BasicTime.Period[from: now, to: entry.expires]; IF thisTtl > -10 THEN RETURN[NIL]; -- Discard old info entry.loaded _ now; entry.referenced _ now; entry.expires _ BasicTime.Update[now, ttl]; entry.ttl _ ttl; RETURN[entry]; }; entry _ MakeDownName[ttl]; entry.name _ name; RETURN[entry]; }; MakeDownName: PROC [ttl: INT] RETURNS [entry: DownNameEntry] = { now: BasicTime.GMT _ BasicTime.Now[]; expires: INT _ ttl; IF expires = 0 THEN expires _ ttlDefault; entry _ NEW[DownNameRecord]; entry^ _ [ loaded: now, referenced: now, expires: BasicTime.Update[now, expires], ttl: ttl ]; downNames _ CONS[entry, downNames]; }; addresses: LIST OF AddressEntry _ NIL; GetAddresses: PUBLIC ENTRY PROC RETURNS [LIST OF AddressEntry] = { RETURN[addresses]; }; AddressLookup: PUBLIC ENTRY PROC [address: IPDefs.Address] RETURNS [entry: AddressEntry] = {RETURN[AddressLookupInternal[address]]}; AddressLookupInternal: PROC [address: IPDefs.Address] RETURNS [entry: AddressEntry] = { FOR list: LIST OF AddressEntry _ addresses, list.rest UNTIL list = NIL DO entry _ list.first; IF entry.address = address THEN { entry.referenced _ BasicTime.Now[]; RETURN; }; ENDLOOP; RETURN[NIL]; }; UpdateAddress: PUBLIC ENTRY PROC [ address: IPDefs.Address, source: IPDefs.Address, ttl: INT, authoritative: BOOL] RETURNS [entry: AddressEntry] = { entry _ AddressLookupInternal[address]; IF entry # NIL THEN { now: BasicTime.GMT _ BasicTime.Now[]; thisTtl: INT = BasicTime.Period[from: now, to: entry.expires]; IF thisTtl < -10 THEN entry.authoritative _ FALSE; IF entry.authoritative AND ~authoritative THEN RETURN[NIL]; IF ~entry.authoritative AND authoritative THEN { entry.names _ NIL; }; entry.source _ source; entry.loaded _ now; entry.referenced _ now; entry.expires _ BasicTime.Update[now, ttl]; entry.ttl _ ttl; entry.authoritative _ authoritative; RETURN[entry]; }; entry _ MakeAddressEntry[source, ttl, authoritative]; entry.address _ address; RETURN[entry]; }; MakeAddressEntry: PROC [ source: IPDefs.Address, ttl: INT, authoritative: BOOL] RETURNS [entry: AddressEntry] = { now: BasicTime.GMT _ BasicTime.Now[]; expires: INT _ ttl; IF expires = 0 THEN expires _ ttlDefault; entry _ NEW[AddressRecord]; entry^ _ [ loaded: now, referenced: now, expires: BasicTime.Update[now, expires], ttl: ttl, source: source, authoritative: authoritative]; addresses _ CONS[entry, addresses]; }; AddNameToAddress: PUBLIC ENTRY PROC [entry: AddressEntry, name: ROPE] = { entry.names _ IPNameSupport.MakeRopeInList[entry.names, name]; }; bogusAddresses: LIST OF BogusAddressEntry _ NIL; GetBogusAddresses: PUBLIC ENTRY PROC RETURNS [LIST OF BogusAddressEntry] = { RETURN[bogusAddresses]; }; BogusAddressLookup: PUBLIC ENTRY PROC [bogus: IPDefs.Address] RETURNS [entry: BogusAddressEntry] = {RETURN[BogusAddressLookupInternal[bogus]]}; BogusAddressLookupInternal: PROC [bogus: IPDefs.Address] RETURNS [entry: BogusAddressEntry] = { FOR list: LIST OF BogusAddressEntry _ bogusAddresses, list.rest UNTIL list = NIL DO entry _ list.first; IF entry.bogus = bogus THEN { entry.referenced _ BasicTime.Now[]; RETURN; }; ENDLOOP; RETURN[NIL]; }; UpdateBogusAddress: PUBLIC ENTRY PROC [ bogus: IPDefs.Address, source: IPDefs.Address, ttl: INT, authoritative: BOOL] RETURNS [entry: BogusAddressEntry] = { entry _ BogusAddressLookupInternal[bogus]; IF entry # NIL THEN { now: BasicTime.GMT _ BasicTime.Now[]; thisTtl: INT = BasicTime.Period[from: now, to: entry.expires]; IF thisTtl < -10 THEN entry.authoritative _ FALSE; IF entry.authoritative AND ~authoritative THEN RETURN[NIL]; IF ~entry.authoritative AND authoritative THEN { NULL; }; entry.source _ source; entry.loaded _ now; entry.referenced _ now; entry.expires _ BasicTime.Update[now, ttl]; entry.ttl _ ttl; entry.authoritative _ authoritative; RETURN[entry]; }; entry _ MakeBogusAddress[source, ttl, authoritative]; entry.bogus _ bogus; RETURN[entry]; }; MakeBogusAddress: PROC [ source: IPDefs.Address, ttl: INT, authoritative: BOOL] RETURNS [entry: BogusAddressEntry] = { now: BasicTime.GMT _ BasicTime.Now[]; expires: INT _ ttl; IF expires = 0 THEN expires _ ttlDefault; entry _ NEW[BogusAddressRecord]; entry^ _ [ loaded: now, referenced: now, expires: BasicTime.Update[now, expires], ttl: ttl, source: source, authoritative: authoritative, bogus: TRASH ]; bogusAddresses _ CONS[entry, bogusAddresses]; }; downAddresses: LIST OF DownAddressEntry _ NIL; GetDownAddresses: PUBLIC ENTRY PROC RETURNS [LIST OF DownAddressEntry] = { RETURN[downAddresses]; }; DownAddressLookup: PUBLIC ENTRY PROC [address: IPDefs.Address] RETURNS [entry: DownAddressEntry] = { entry _ DownAddressLookupInternal[address]; IF entry # NIL THEN { now: BasicTime.GMT _ BasicTime.Now[]; thisTtl: INT = BasicTime.Period[from: now, to: entry.expires]; IF thisTtl < -10 THEN RETURN[NIL];}; -- Don't show expired items RETURN[entry]}; DownAddressLookupInternal: PROC [address: IPDefs.Address] RETURNS [entry: DownAddressEntry] = { FOR list: LIST OF DownAddressEntry _ downAddresses, list.rest UNTIL list = NIL DO entry _ list.first; IF entry.address = address THEN { entry.referenced _ BasicTime.Now[]; RETURN; }; ENDLOOP; RETURN[NIL]; }; UpdateDownAddress: PUBLIC ENTRY PROC [address: IPDefs.Address, ttl: INT] RETURNS [entry: DownAddressEntry] = { entry _ DownAddressLookupInternal[address]; IF entry # NIL THEN { now: BasicTime.GMT _ BasicTime.Now[]; thisTtl: INT = BasicTime.Period[from: now, to: entry.expires]; IF thisTtl > -10 THEN RETURN[NIL]; -- Discard old info entry.loaded _ now; entry.referenced _ now; entry.expires _ BasicTime.Update[now, ttl]; entry.ttl _ ttl; RETURN[entry]; }; entry _ MakeDownAddress[ttl]; entry.address _ address; RETURN[entry]; }; MakeDownAddress: PROC [ttl: INT] RETURNS [entry: DownAddressEntry] = { now: BasicTime.GMT _ BasicTime.Now[]; expires: INT _ ttl; IF expires = 0 THEN expires _ ttlDefault; entry _ NEW[DownAddressRecord]; entry^ _ [ loaded: now, referenced: now, expires: BasicTime.Update[now, expires], ttl: ttl, address: TRASH ]; downAddresses _ CONS[entry, downAddresses]; }; downServers: LIST OF DownServerEntry _ NIL; GetDownServers: PUBLIC ENTRY PROC RETURNS [LIST OF DownServerEntry] = { RETURN[downServers]; }; DownServerLookup: PUBLIC ENTRY PROC [address: IPDefs.Address] RETURNS [entry: DownServerEntry] = { entry _ DownServerLookupInternal[address]; IF entry # NIL THEN { now: BasicTime.GMT _ BasicTime.Now[]; thisTtl: INT = BasicTime.Period[from: now, to: entry.expires]; IF thisTtl < -10 THEN RETURN[NIL];}; -- Don't show expired items RETURN[entry]}; DownServerLookupInternal: PROC [address: IPDefs.Address] RETURNS [entry: DownServerEntry] = { FOR list: LIST OF DownServerEntry _ downServers, list.rest UNTIL list = NIL DO entry _ list.first; IF entry.address = address THEN { entry.referenced _ BasicTime.Now[]; RETURN; }; ENDLOOP; RETURN[NIL]; }; UpdateDownServer: PUBLIC ENTRY PROC [ address: IPDefs.Address, ttl: INT] RETURNS [entry: DownServerEntry] = { entry _ DownServerLookupInternal[address]; IF entry # NIL THEN { now: BasicTime.GMT _ BasicTime.Now[]; thisTtl: INT = BasicTime.Period[from: now, to: entry.expires]; IF thisTtl > -10 THEN RETURN[NIL]; -- Discard old info entry.loaded _ now; entry.referenced _ now; entry.expires _ BasicTime.Update[now, ttl]; entry.ttl _ ttl; RETURN[entry]; }; entry _ MakeDownServer[ttl]; entry.address _ address; RETURN[entry]; }; MakeDownServer: PROC [ttl: INT] RETURNS [entry: DownServerEntry] = { now: BasicTime.GMT _ BasicTime.Now[]; expires: INT _ ttl; IF expires = 0 THEN expires _ ttlDefault; entry _ NEW[DownServerRecord]; entry^ _ [ loaded: now, referenced: now, expires: BasicTime.Update[now, expires], ttl: ttl, address: TRASH ]; downServers _ CONS[entry, downServers]; }; zones: LIST OF ZoneEntry _ NIL; GetZones: PUBLIC ENTRY PROC RETURNS [LIST OF ZoneEntry] = { RETURN[zones]; }; GetZone: PUBLIC ENTRY PROC [name: ROPE] RETURNS [entry: ZoneEntry] = { bestEntry: ZoneEntry _ NIL; FOR list: LIST OF ZoneEntry _ zones, list.rest UNTIL list = NIL DO entry _ list.first; IF Rope.Match[Rope.Cat["*", entry.zone], name, FALSE] THEN { IF bestEntry = NIL THEN bestEntry _ entry ELSE IF Rope.Length[bestEntry.zone] < Rope.Length[entry.zone] THEN bestEntry _ entry}; ENDLOOP; IF bestEntry # NIL THEN bestEntry.zoneLookup _ bestEntry.zoneLookup + 1; RETURN[bestEntry]; }; ZoneLookup: PUBLIC ENTRY PROC [zone: ROPE] RETURNS [entry: ZoneEntry] = { RETURN[ZoneLookupInternal[zone]]; }; ZoneLookupInternal: PROC [zone: ROPE] RETURNS [entry: ZoneEntry] = { FOR list: LIST OF ZoneEntry _ zones, list.rest UNTIL list = NIL DO entry _ list.first; IF Rope.Equal[entry.zone, zone, FALSE] THEN { entry.zoneLookup _ entry.zoneLookup + 1; RETURN; }; ENDLOOP; RETURN[NIL]; }; UpdateZone: PUBLIC ENTRY PROC [ name: ROPE, source: IPDefs.Address, ttl: INT, authoritative: BOOL] RETURNS [entry: ZoneEntry] = { now: BasicTime.GMT _ BasicTime.Now[]; thisTtl: INT; entry _ ZoneLookupInternal[name]; IF entry # NIL THEN { thisTtl _ BasicTime.Period[from: now, to: entry.expires]; IF thisTtl < -10 THEN entry.authoritative _ FALSE; IF entry.authoritative AND ~authoritative THEN RETURN[NIL]; IF ~entry.authoritative AND authoritative THEN { entry.servers _ NIL; }; entry.source _ source; entry.loaded _ now; entry.referenced _ now; entry.expires _ BasicTime.Update[now, ttl]; entry.ttl _ ttl; entry.authoritative _ authoritative; entry.zone _ name; RETURN[entry]; }; entry _ MakeZoneEntry[source, ttl, authoritative]; entry.zone _ name; RETURN[entry]; }; AddServer: PUBLIC ENTRY PROC [entry: ZoneEntry, server: ROPE] = { entry.servers _ IPNameSupport.MakeRopeInList[entry.servers, server]; }; MakeZoneEntry: PROC [source: IPDefs.Address, ttl: INT, authoritative: BOOL] RETURNS [entry: ZoneEntry] = { now: BasicTime.GMT _ BasicTime.Now[]; expires: INT _ ttl; IF expires = 0 THEN expires _ ttlDefault; entry _ NEW[ZoneRecord]; entry^ _ [ loaded: now, referenced: now, expires: BasicTime.Update[now, expires], ttl: ttl, source: source, authoritative: authoritative ]; zones _ CONS[entry, zones]; }; histograms: LIST OF HistogramEntry _ NIL; GetHistograms: PUBLIC ENTRY PROC RETURNS [LIST OF HistogramEntry] = { RETURN[histograms]; }; AddToCacheHits: PUBLIC ENTRY PROC [server: IPDefs.Address, type: IPNameCache.CacheType] = { histogram: HistogramEntry _ FindHistogram[server]; histogram.cacheHits[type] _ histogram.cacheHits[type].SUCC; }; AddToProbes: PUBLIC ENTRY PROC [server: IPDefs.Address, type: IPNameCache.ProbeType] = { histogram: HistogramEntry _ FindHistogram[server]; histogram.probes[type] _ histogram.probes[type].SUCC; }; AddToLost: PUBLIC ENTRY PROC [server: IPDefs.Address] = { histogram: HistogramEntry _ FindHistogram[server]; histogram.lost _ histogram.lost.SUCC; }; AddToCounter: PUBLIC ENTRY PROC [server: IPDefs.Address, ms: INT] = { histogram: HistogramEntry _ FindHistogram[server]; index: INT; ms _ ms + IPNameCache.histogramSlotSize - 1; index _ ms/IPNameCache.histogramSlotSize; IF index >= IPNameCache.histogramSlots THEN index _ IPNameCache.histogramSlots-1; histogram.counters[index] _ histogram.counters[index].SUCC; }; FindHistogram: PROC [server: IPDefs.Address] RETURNS[ histogram: HistogramEntry] = { FOR list: LIST OF HistogramEntry _ histograms, list.rest UNTIL list = NIL DO histogram _ list.first; IF histogram.server = server THEN EXIT; REPEAT FINISHED => { histogram _ NEW[HistogramRecord]; histogram^ _ [ server: server, counters: ALL[0] ]; histograms _ CONS[histogram, histograms]; }; ENDLOOP; }; END. ψIPNameCacheImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Hal Murray June 29, 1985 3:46:01 pm PDT John Larson, July 10, 1987 2:54:54 pm PDT -- noticeable default ttl Name to Address cache Discard old info Alias to Name cache Discard old info MX cache Discard old info Bogus Name cache Discard old info Down Name cache Address to Name cache Discard old info Bogus Address cache Discard old info Down Address cache Down Server cache Zone to Server cache Discard old info Κ°˜šœ™Icodešœ Οmœ1™Jšžœžœžœ˜2Jš žœžœžœžœžœ˜;šžœžœžœ˜0Jšœ™Jšœžœ˜—Jšœ˜Jšœ˜Jšœ˜Jšœ+˜+Jšœ˜Jšœ$˜$Jšžœ ˜—Jšœ2˜2Jšœ˜Jšžœ ˜—šŸ œžœ˜Jšœžœžœ˜6Jšžœ˜Jšœžœ˜%Jšœ žœ˜Jšžœ žœ˜)Jšœžœ ˜šœ ˜ Jšœ ˜ Jšœ˜Jšœ(˜(J˜ Jšœ˜Jšœ˜—Jšœžœ˜—šŸœžœžœžœ0˜SJšœO˜OJ˜——J™šœ™Jšœ žœžœžœ˜"šŸ œžœžœžœžœžœžœžœ ˜RJ˜—JšŸ œžœžœžœ žœžœžœ˜pJ˜šŸœžœ žœžœ˜Gš žœžœžœ!žœžœž˜EJšœ˜šžœ žœžœ˜/Jšœ#˜#Jšžœ˜ —Jšžœ˜—Jšžœžœ˜J˜—šŸ œžœžœžœ˜ Jšœžœžœžœ˜DJšžœ˜Jšœ#˜#šžœ žœžœ˜Jšœžœ˜%Jšœ žœ2˜>Jšžœžœžœ˜2Jš žœžœžœžœžœ˜;šžœžœžœ˜0Jšœ™Jšœ žœ˜—Jšœ˜Jšœ˜Jšœ˜Jšœ+˜+Jšœ˜Jšœ$˜$Jšžœ ˜—Jšœ3˜3Jšœ˜Jšžœ ˜—šŸœžœ˜Jšœžœžœ˜6Jšžœ˜Jšœžœ˜%Jšœ žœ˜Jšžœ žœ˜)Jšœžœ˜šœ ˜ Jšœ ˜ Jšœ˜Jšœ(˜(J˜ Jšœ˜Jšœ˜—Jšœ žœ˜#—J˜š Ÿœžœžœžœžœ˜EJšœ˜J˜J˜——šœ™Jšœžœžœ žœ˜šŸ œžœžœžœžœžœžœžœ ˜MJ˜—JšŸœžœžœžœžœžœžœ˜eJ˜šŸœžœžœžœ˜@š žœžœžœžœžœž˜AJšœ˜šžœžœžœ˜-Jšœ#˜#Jšžœ˜ —Jšžœ˜—Jšžœžœ˜J˜—šŸœžœžœžœ˜Jšœžœžœžœ˜CJšžœ˜Jšœ˜šžœ žœžœ˜Jšœžœ˜%Jšœ žœ2˜>Jšžœžœžœ˜2Jš žœžœžœžœžœ˜;šžœžœžœ˜0Jšœ™Jšœžœ˜—Jšœ˜Jšœ˜Jšœ˜Jšœ+˜+Jšœ˜Jšœ$˜$Jšžœ ˜—Jšœ0˜0Jšœ˜Jšžœ ˜—šŸ œžœ˜Jšœžœžœ˜6Jšžœ˜Jšœžœ˜%Jšœ žœ˜Jšžœ žœ˜)Jšœžœ ˜šœ ˜ Jšœ ˜ Jšœ˜Jšœ(˜(J˜ Jšœ˜Jšœ˜—Jšœ žœ˜!—J˜šŸ œžœžœžœ+˜Išžœ+žœ˜2Jšœžœ˜1J˜——šŸœžœ žœžœ#˜IJšžœžœ˜š žœžœžœ!žœžœž˜EJš žœ,žœžœ-žœžœžœ˜wJšžœ˜Jšžœžœ˜—Jšœ˜J˜J˜——šœ™Jšœ žœžœžœ˜)šŸ œžœžœžœžœžœžœžœ˜\J˜—JšŸœžœžœžœ žœžœžœ"˜|J˜šŸœžœ žœžœ˜Oš žœžœžœ(žœžœž˜LJšœ˜šžœ žœžœ˜/Jšœ#˜#Jšžœ˜ —Jšžœ˜—Jšžœžœ˜J˜—šŸœžœžœžœ˜$Jšœžœžœžœ˜DJšžœ˜#Jšœ'˜'šžœ žœžœ˜Jšœžœ˜%Jšœ žœ2˜>Jšžœžœžœ˜2Jš žœžœžœžœžœ˜;šžœžœžœ˜0Jšœ™Jšžœ˜—Jšœ˜Jšœ˜Jšœ˜Jšœ+˜+Jšœ˜Jšœ$˜$Jšžœ ˜—Jšœ2˜2Jšœ˜Jšžœ ˜—šŸ œžœ˜Jšœžœžœ˜6Jšžœ˜#Jšœžœ˜%Jšœ žœ˜Jšžœ žœ˜)Jšœžœ˜šœ ˜ Jšœ ˜ Jšœ˜Jšœ(˜(J˜ Jšœ˜Jšœ˜—Jšœ žœ˜)J˜——šœ™Jšœ žœžœžœ˜'JšŸ œžœžœžœžœžœžœ˜Dšžœ˜J˜—š Ÿœžœžœžœžœžœ˜QJšœ%˜%šžœ žœžœ˜Jšœžœ˜%Jšœ žœ2˜>Jš žœžœžœžœΟc˜@—Jšžœ ˜—J˜J˜šŸœžœžœžœ˜Lš žœžœžœ&žœžœž˜JJšœ˜šžœžœžœ˜-Jšœ#˜#Jšžœ˜ —Jšžœ˜—Jšžœžœ˜J˜—šŸœžœžœžœ˜#Jšœžœžœ˜Jšžœ˜"Jšœ%˜%šžœ žœžœ˜Jšœžœ˜%Jšœ žœ2˜>Jšžœžœžœžœ˜#Jš ˜Jšœ˜Jšœ˜Jšœ+˜+Jšœ˜Jšžœ ˜—Jšœ˜Jšœ˜Jšžœ ˜—šŸ œžœžœžœ˜@Jšœžœ˜%Jšœ žœ˜Jšžœ žœ˜)Jšœžœ˜šœ ˜ Jšœ ˜ Jšœ˜Jšœ(˜(Jšœ ˜ —Jšœ žœ˜'——šœ™Jšœ žœžœžœ˜&JšŸ œžœžœžœžœžœžœžœ˜XJ˜Jš Ÿ œžœžœžœžœžœ"˜„J˜šŸœžœžœ˜Wš žœžœžœ%žœžœž˜IJšœ˜šžœžœ˜!Jšœ#˜#Jšžœ˜ —Jšžœ˜—Jšžœžœ˜J˜—šŸ œžœžœžœ˜"Jšœ6žœžœ˜PJšžœ˜!Jšœ'˜'šžœ žœžœ˜Jšœžœ˜%Jšœ žœ2˜>Jšžœžœžœ˜2Jš žœžœžœžœžœ˜;šžœžœžœ˜0Jšœ™Jšœžœ˜—Jšœ˜Jšœ˜Jšœ˜Jšœ+˜+Jšœ˜Jšœ$˜$Jšžœ ˜—Jšœ5˜5Jšœ˜Jšžœ ˜J˜—šŸœžœ˜Jšœžœžœ˜6Jšžœ˜!Jšœžœ˜%Jšœ žœ˜Jšžœ žœ˜)Jšœžœ˜šœ ˜ Jšœ ˜ Jšœ˜Jšœ(˜(J˜ Jšœ˜Jšœ˜—Jšœ žœ˜'—š Ÿœžœžœžœžœ˜IJšœA˜AJ˜——J™šœ™Jšœžœžœžœ˜0šŸœžœžœžœžœžœžœžœ˜gJ˜—Jš Ÿœžœžœžœžœžœ%˜J˜šŸœžœžœ˜_š žœžœžœ/žœžœž˜SJšœ˜šžœžœ˜Jšœ#˜#Jšžœ˜ —Jšžœ˜—Jšžœžœ˜J˜—šŸœžœžœžœ˜'Jšœ4žœžœ˜NJšžœ˜&Jšœ*˜*šžœ žœžœ˜Jšœžœ˜%Jšœ žœ2˜>Jšžœžœžœ˜2Jš žœžœžœžœžœ˜;šžœžœžœ˜0Jšœ™Jšžœ˜—Jšœ˜Jšœ˜Jšœ˜Jšœ+˜+Jšœ˜Jšœ$˜$Jšžœ ˜—Jšœ5˜5Jšœ˜Jšžœ ˜—šŸœžœ˜Jšœžœžœ˜6Jšžœ˜&Jšœžœ˜%Jšœ žœ˜Jšžœ žœ˜)Jšœžœ˜ šœ ˜ Jšœ ˜ Jšœ˜Jšœ(˜(J˜ Jšœ˜Jšœ˜Jšœžœ˜—Jšœžœ˜1——šœ™Jšœžœžœžœ˜.šŸœžœžœžœžœžœžœžœ˜dJ˜—š Ÿœžœžœžœžœ˜dJšœ+˜+šžœ žœžœ˜Jšœžœ˜%Jšœ žœ2˜>Jš žœžœžœžœ ˜@—Jšžœ ˜—J˜šŸœžœžœ˜_š žœžœžœ-žœžœž˜QJšœ˜šžœžœ˜!Jšœ#˜#Jšžœ˜ —Jšžœ˜—Jšžœžœ˜J˜—š Ÿœžœžœžœ žœ˜HJšžœ˜%Jšœ+˜+šžœ žœžœ˜Jšœžœ˜%Jšœ žœ2˜>Jšžœžœžœžœ˜#Jš ˜Jšœ˜Jšœ˜Jšœ+˜+Jšœ˜Jšžœ ˜—Jšœ˜Jšœ˜Jšžœ ˜—šŸœžœžœžœ˜FJšœžœ˜%Jšœ žœ˜Jšžœ žœ˜)Jšœžœ˜šœ ˜ Jšœ ˜ Jšœ˜Jšœ(˜(J˜ Jšœ žœ˜—Jšœžœ˜/——Jšœ™™Jšœ žœžœžœ˜+JšŸœžœžœžœžœžœžœ˜Hšžœ˜J˜—š Ÿœžœžœžœžœ˜bJšœ*˜*šžœ žœžœ˜Jšœžœ˜%Jšœ žœ2˜>Jš žœžœžœžœ ˜@—Jšžœ ˜—J˜J˜šŸœžœžœ˜]š žœžœžœ*žœžœž˜NJšœ˜šžœžœ˜!Jšœ#˜#Jšžœ˜ —Jšžœ˜—Jšžœžœ˜J˜—šŸœžœžœžœ˜%Jšœžœ˜#Jšžœ˜$Jšœ*˜*šžœ žœžœ˜Jšœžœ˜%Jšœ žœ2˜>Jšžœžœžœžœ˜#Jš ˜Jšœ˜Jšœ˜Jšœ+˜+Jšœ˜Jšžœ ˜—Jšœ˜Jšœ˜Jšžœ ˜—šŸœžœžœžœ˜DJšœžœ˜%Jšœ žœ˜Jšžœ žœ˜)Jšœžœ˜šœ ˜ Jšœ ˜ Jšœ˜Jšœ(˜(Jšœ ˜ Jšœ žœ˜—Jšœžœ˜+——šœ™Jšœžœžœ žœ˜JšŸœžœžœžœžœžœžœžœ ˜MJ˜š Ÿœžœžœžœžœžœ˜FJšœžœ˜š žœžœžœžœžœž˜BJšœ˜Jšžœ-žœžœ˜=šœžœ žœžœž˜0Jšœžœ7žœ˜T—Jšžœ˜—Jšžœ žœžœ1˜HJšžœ˜J˜—š Ÿ œžœžœžœžœžœ˜IJšžœ˜$J˜—šŸœžœžœžœ˜Eš žœžœžœžœžœž˜BJšœ˜šžœžœžœ˜-Jšœ(˜(Jšžœ˜ —Jšžœ˜—Jšžœžœ˜J˜J˜—šŸ œžœžœžœ˜Jšœžœžœžœ˜CJšžœ˜Jšœžœ˜%Jšœ žœ˜ Jšœ!˜!˜šžœ žœžœ˜Jšœ9˜9Jšžœžœžœ˜2Jš žœžœžœžœžœ˜;šžœžœžœ˜0Jšœ™Jšœžœ˜—Jšœ˜Jšœ˜Jšœ˜Jšœ+˜+Jšœ˜Jšœ$˜$Jšœ˜Jšžœ ˜J˜——Jšœ2˜2Jšœ˜Jšžœ ˜J˜—š Ÿ œžœžœžœžœ˜AJšœG˜GJ˜—š Ÿ œžœžœžœžœ˜jJšœžœ˜%Jšœ žœ˜Jšžœ žœ˜)Jšœžœ ˜šœ ˜ Jšœ ˜ Jšœ˜Jšœ(˜(J˜ Jšœ˜Jšœ˜—Jšœžœ˜—Jšœ žœžœžœ˜)JšŸ œžœžœžœžœžœžœžœ˜\J˜šŸœžœžœžœ:˜[Jšœ2˜2Jšœ6žœ˜>J˜—šŸ œžœžœžœ:˜XJšœ2˜2Jšœ0žœ˜8J˜—šŸ œžœžœžœ˜9Jšœ2˜2Jšœ žœ˜(J˜—š Ÿ œžœžœžœžœ˜EJšœ2˜2Jšœžœ˜ Jšœ,˜,Jšœ)˜)Jšžœ%žœ&˜QJšœ6žœ˜>—J˜šŸ œžœžœ ˜Tš žœžœžœ(žœžœž˜LJšœ˜Jšžœžœžœ˜'šžœžœ˜Jšœ žœ˜!˜J˜Jšœ žœ˜—Jšœ žœ˜,—Jšžœ˜ ——J˜J˜Jšžœ˜J˜J˜J˜—J˜—…—OζnŽ