java.lang.Object
net.i2p.router.tunnel.BloomFilterIVValidator
- All Implemented Interfaces:
IVValidator
Manage the IV validation for all of the router's tunnels by way of a big decaying bloom filter.
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classChooses the filter exponent from measured load and the heap budget.Field Summary
Modifier and TypeFieldDescriptionprivate final RouterContextThe router doing the validating.private DecayingBloomFilterRemembers the initialization vectors already seen.private final LogLogger for this class.Manages the filter's size.static final intDefault exponent when nothing is configured: 2^23 bits per buffer, a 2 MB pair, which holds roughly 600k entries at a 1.5E-3 false positive rate.(package private) static final doubleFraction of max heap the filter may claim.private static final intAfter 2*halflife, an entry is completely forgotten from the bloom filter.(package private) static final longHard floor on the filter's byte budget, so a tiny heap still gets one.static final intFloor for the exponent: 2^20 is a 0.5 MB pair.private static final longLeast free heap for which the bloom filter is worth using.private static final intShare bandwidth at or above which the fixed-memory filter is always worth using.private static final StringFor testing.static final StringProperty the Tuner drives the filter exponent through.private static final StringFor testing.Constructor Summary
ConstructorsConstructorDescriptionBloomFilterIVValidator(RouterContext ctx, int KBps) Construct the validator, choosing a starting filter size from the configured share and the heap, then leaving the size to be retuned from measured load.Method Summary
Modifier and TypeMethodDescriptionvoiddestroy()Stop the decaying filter.static longMemory this filter may claim, as a fraction of the heap, with a floor so a small heap still gets a usable filter.intThe filter's size exponent, or 0 when the set is in use.intEntries seen in the most recently completed decay window, which is what the size has to be chosen against.doubleThe live false positive rate, or 0 for the set, which is exact.getSizer()The retuning policy for this validator, or null when the filter is off.booleanreceiveIV(byte[] ivData, int ivOffset, byte[] payload, int payloadOffset) Receive the IV for the tunnel message, returning true if it is valid, or false if it has already been used (or is otherwise invalid).voidreconfigure(int m, int KBps) Replace the filter with one of a different size, or with the set.private voidwarn(long maxMemory, int KBps, long recMaxMem, int threshKBps) Log a one-time WARN when the IV filter may be too small.
Field Details
_context
The router doing the validating._log
Logger for this class._filter
Remembers the initialization vectors already seen._sizer
Manages the filter's size. Kept behind a field so the router can hold the filter for the low-memory case and still retune it later.HALFLIFE_MS
private static final int HALFLIFE_MSAfter 2*halflife, an entry is completely forgotten from the bloom filter. To avoid the issue of overlap within different tunnels, this is set higher than it needs to be.- See Also:
PROP_FILTER_M
Property the Tuner drives the filter exponent through. The starting value is a property rather than a constant so an operator can pin it before the first tuning cycle.- See Also:
DEFAULT_FILTER_M
public static final int DEFAULT_FILTER_MDefault exponent when nothing is configured: 2^23 bits per buffer, a 2 MB pair, which holds roughly 600k entries at a 1.5E-3 false positive rate. That covers a 1 MBps share with a wide margin.- See Also:
MIN_FILTER_M
public static final int MIN_FILTER_MFloor for the exponent: 2^20 is a 0.5 MB pair.- See Also:
FILTER_HEAP_FRACTION
static final double FILTER_HEAP_FRACTIONFraction of max heap the filter may claim. The rest is left for transport buffers, the netdb, and the collector.- See Also:
MIN_FILTER_BUDGET
static final long MIN_FILTER_BUDGETHard floor on the filter's byte budget, so a tiny heap still gets one.- See Also:
MIN_SHARE_KBPS_TO_USE_BLOOM
private static final int MIN_SHARE_KBPS_TO_USE_BLOOMShare bandwidth at or above which the fixed-memory filter is always worth using. Below it the set is only kept when memory is genuinely tight.- See Also:
MIN_MEM_TO_USE_BLOOM
private static final long MIN_MEM_TO_USE_BLOOMLeast free heap for which the bloom filter is worth using.- See Also:
PROP_FORCE
PROP_DISABLE
Constructor Details
BloomFilterIVValidator
Construct the validator, choosing a starting filter size from the configured share and the heap, then leaving the size to be retuned from measured load.The initial choice deliberately favours the fixed-memory filter over the set: a pair of 2^23 bit arrays is 2 MB whatever the traffic, whereas the set costs about 72 bytes per entry and is unbounded until its cap. So the set is used only when both the share is small and the heap is small, and it is replaced by a filter as soon as the budget allows.
- Parameters:
ctx- the router contextKBps- the share bandwidth in KBps
Method Details
filterBudgetBytes
public static long filterBudgetBytes()Memory this filter may claim, as a fraction of the heap, with a floor so a small heap still gets a usable filter.- Returns:
- the budget in bytes, never below the 1 MB floor
getFilterM
public int getFilterM()The filter's size exponent, or 0 when the set is in use.- Returns:
- the exponent, or 0 for the set or when disabled
getLastWindowCount
public int getLastWindowCount()Entries seen in the most recently completed decay window, which is what the size has to be chosen against. Zero until the first decay.- Returns:
- entries in the last window
getMeasuredFalsePositiveRate
public double getMeasuredFalsePositiveRate()The live false positive rate, or 0 for the set, which is exact.- Returns:
- the current false positive rate
reconfigure
public void reconfigure(int m, int KBps) Replace the filter with one of a different size, or with the set. A resize discards the buffered IVs, so for a short window a repeated IV could go unnoticed; the caller is expected to only do this on a decay boundary and at most one step at a time.- Parameters:
m- the new exponent, 0 to switch to the memory-proportional setKBps- the configured share in KBps, not consulted here; the set's cap comes from the heap budget
getSizer
The retuning policy for this validator, or null when the filter is off.- Returns:
- the sizer, or null
receiveIV
public boolean receiveIV(byte[] ivData, int ivOffset, byte[] payload, int payloadOffset) Description copied from interface:IVValidatorReceive the IV for the tunnel message, returning true if it is valid, or false if it has already been used (or is otherwise invalid). To prevent colluding attackers from successfully tagging the tunnel by switching the IV and the first block of the message, the validator should treat the XOR of the IV and the first block as the unique identifier, not the IV alone (since the tunnel is encrypted via AES/CBC). Thanks to dvorak for pointing out that tagging!- Specified by:
receiveIVin interfaceIVValidator- Parameters:
ivData- data will not be modifiedivOffset- offset of the IV in the iv arraypayload- will not be modifiedpayloadOffset- offset of the payload in the payload array- Returns:
- true if valid, false if already used or otherwise invalid
destroy
public void destroy()Stop the decaying filter.warn
private void warn(long maxMemory, int KBps, long recMaxMem, int threshKBps) Log a one-time WARN when the IV filter may be too small.- Parameters:
maxMemory- the maximum memory available to the JVM, in bytesKBps- the configured share bandwidth in KBpsrecMaxMem- the recommended minimum memory in bytes, the amount to raise the setting tothreshKBps- the share bandwidth in KBps above which the memory recommendation applies