sonar icon indicating copy to clipboard operation
sonar copied to clipboard

Feature Request: Invalidate IP entry in rate-limiter before transfer

Open whiler-sesame opened this issue 1 year ago • 6 comments

Information

Drop IP from Velocity rate-limiter before transferring (1.20.5) players again to the same server, probably make it an option.

Reason

A usual configuration of the rate-limiter is about 5 seconds. Sonar verifies the client much quicker. Manually removing the IP from cache before transferring might allow not to disable or lower rate-limits and still be convenient for players.

Additional information

These are "internals". Sample code for any Velocity plugin with access to proxy module, not actually tested:

import com.github.benmanes.caffeine.cache.Cache;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
import com.velocitypowered.api.event.proxy.ProxyReloadEvent;
import com.velocitypowered.proxy.VelocityServer;
import com.velocitypowered.proxy.util.ratelimit.CaffeineCacheRatelimiter;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.net.InetAddress;

public class Sample {
    private final MethodHandle cacheGetter;
    private Cache<InetAddress, Long> cache;

    public Sample() throws NoSuchFieldException, IllegalAccessException {
        this.cacheGetter = MethodHandles.privateLookupIn(CaffeineCacheRatelimiter.class, MethodHandles.lookup())
                .findGetter(CaffeineCacheRatelimiter.class, "expiringCache", Cache.class);
        this.loadCache();
    }

    public void dropFromCache(InetAddress address) {
        if (this.cache == null) return; // Not tested for races
        this.cache.invalidate(address);
    }

    @Subscribe
    public void proxyInitializeEvent(ProxyInitializeEvent event) {
        this.loadCache();
    }

    @Subscribe
    public void proxyReloadEvent(ProxyReloadEvent event) {
        this.loadCache();
    }

    private void loadCache() {
        try {
            VelocityServer server = ...; // Obtain from plugin
            if (!(server.getIpAttemptLimiter() instanceof CaffeineCacheRatelimiter limiter)) {
                this.cache = null;
                return;
            }
            this.cache = (Cache<InetAddress, Long>) this.cacheGetter.invoke(limiter);
        } catch (Throwable e) {
            this.cache = null;
            // Handle errors here
        }
    }
}

whiler-sesame avatar Aug 26 '24 03:08 whiler-sesame