Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.text.MessageFormat;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
Expand Down Expand Up @@ -116,22 +115,36 @@ public void debug(String pattern, Object... arguments) {
private @NotNull NetworkFilterResult check(@NotNull String ip) {
long startTime = System.nanoTime();

// cache
Optional<FilterResult> cached = Optional.ofNullable(this.filterCache.getIfPresent(ip));
if (cached.isPresent()) {
this.debug("[{0}] Result is cached: {1}", ip, cached.get());
FilterResult cached = this.filterCache.getIfPresent(ip);
if (cached != null) {
this.debug("[{0}] Result is cached: {1}", ip, cached);

return new NetworkFilterResult(
cached.get().block(),
cached.get().asn(),
cached.get().org(),
cached.block(),
cached.asn(),
cached.org(),
ip,
true,
TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime)
);
}

// ignore
FilterResult filterResult = this.filterCache.get(ip, this::loadFilterResult);

this.debug("[{0}] Requested: {1}", ip, filterResult);

return new NetworkFilterResult(
filterResult.block(),
filterResult.asn(),
filterResult.org(),
ip,
false,
TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime)
);
}

private @NotNull FilterResult loadFilterResult(@NotNull String ip) {

try {
for (String network : this.configManager.getConfig().getIgnore().getNetworks()) {
if (!network.contains("/")) {
Expand All @@ -142,54 +155,28 @@ public void debug(String pattern, Object... arguments) {
SubnetUtils subnetUtils = new SubnetUtils(network);

if (subnetUtils.getInfo().isInRange(ip)) {
FilterResult filterResult = new FilterResult(false, null, null);

this.filterCache.put(ip, filterResult);

this.debug("[{0}] IP is in ignored range: {1}", ip, network);

return new NetworkFilterResult(
false,
-1,
"Ignored Network",
ip,
false,
TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime)
);
return new FilterResult(false, -1, "Ignored Network");
}
}
} catch (Throwable t) {
this.logger.log(Level.SEVERE, "Error while checking inetAddress for ignored", t);
}

// check
FilterResult filterResult;
try {
filterResult = this.filterService.check(ip);
return this.filterService.check(ip);
} catch (FilterException e) {
this.logger.log(Level.SEVERE, "Could not check ip " + ip + " (status: " + e.getCode() + ", body: " + e.getBody().toString() + ")", e);

// TODO: make configurable (something like "blockOnFilterServiceError") - should apply on rate limit?
filterResult = new FilterResult(false, null, null);
return new FilterResult(false, null, null);
} catch (Throwable t) {
this.logger.log(Level.SEVERE, "Could not check ip " + ip, t);

// TODO: make configurable (something like "blockOnUnexpectedError")
filterResult = new FilterResult(false, null, null);
return new FilterResult(false, null, null);
}

this.filterCache.put(ip, filterResult);

this.debug("[{0}] Requested: {1}", ip, filterResult);

return new NetworkFilterResult(
filterResult.block(),
filterResult.asn(),
filterResult.org(),
ip,
false,
TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime)
);
}

public void sendNotify(NetworkFilterResult result, String name, UUID uuid) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,25 @@
import ls.ni.networkfilter.common.cache.types.NoopCache;
import ls.ni.networkfilter.common.cache.types.RedisCache;
import ls.ni.networkfilter.common.config.Config;
import ls.ni.networkfilter.common.config.cache.types.ApiCacheSettings;
import org.jetbrains.annotations.NotNull;

import java.time.Duration;

public class CacheFactory {

public static Cache create(@NotNull Config config) {
ApiCacheSettings apiCache = config.getApiCache();
if (apiCache != null && Boolean.TRUE.equals(apiCache.getEnabled())) {
long maximumSize = apiCache.getMaximumSize() != null ? apiCache.getMaximumSize() : 1000L;
long cacheTimeMinutes = apiCache.getCacheTimeMinutes() != null ? apiCache.getCacheTimeMinutes() : 60L;

return new CaffeineCache(
maximumSize,
Duration.ofMinutes(cacheTimeMinutes)
);
}

return switch (config.getCache()) {
case DISABLED -> new NoopCache();
case LOCAL -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import lombok.NoArgsConstructor;
import ls.ni.networkfilter.common.config.cache.CacheSettings;
import ls.ni.networkfilter.common.config.cache.CacheType;
import ls.ni.networkfilter.common.config.cache.types.ApiCacheSettings;
import ls.ni.networkfilter.common.config.consequence.ConsequenceSettings;
import ls.ni.networkfilter.common.config.ignore.IgnoreSettings;
import ls.ni.networkfilter.common.config.notify.NotifySettings;
Expand Down Expand Up @@ -37,6 +38,9 @@ public class Config {
@NotNull
private CacheSettings caches;

@Valid
private ApiCacheSettings apiCache;

@Valid
@NotNull
private ServiceSettings services;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package ls.ni.networkfilter.common.config.cache.types;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class ApiCacheSettings {

private Boolean enabled;

private Long maximumSize;

private Long cacheTimeMinutes;
}
7 changes: 7 additions & 0 deletions common/src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ caches:
uri: "redis://user:password@localhost:6379"
cacheTimeMinutes: 15

# Local in-memory cache for API/filter results.
# If enabled, this is checked before every API request.
apiCache:
enabled: true
maximumSize: 1000
cacheTimeMinutes: 60

services:
# https://nf.ni.ls
networkfilter:
Expand Down