Skip to content
This repository has been archived by the owner on Jul 15, 2022. It is now read-only.

Commit

Permalink
Merge branch 'master' of https://github.com/SpigotMC/BungeeCord into …
Browse files Browse the repository at this point in the history
…SpigotMC-master
  • Loading branch information
sleiss committed Dec 27, 2018
2 parents c59a4d6 + 5ef5dd2 commit 1cf1651
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 17 deletions.
2 changes: 1 addition & 1 deletion proxy/src/main/java/net/md_5/bungee/BungeeCord.java
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ public void start() throws Exception

if ( config.getThrottle() > 0 )
{
connectionThrottle = new ConnectionThrottle( config.getThrottle() );
connectionThrottle = new ConnectionThrottle( config.getThrottle(), config.getThrottleLimit() );
}
startListeners();

Expand Down
30 changes: 23 additions & 7 deletions proxy/src/main/java/net/md_5/bungee/ConnectionThrottle.java
Original file line number Diff line number Diff line change
@@ -1,29 +1,45 @@
package net.md_5.bungee;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import java.net.InetAddress;
import java.util.concurrent.TimeUnit;

public class ConnectionThrottle
{

private final Cache<InetAddress, Boolean> throttle;
private final LoadingCache<InetAddress, Integer> throttle;
private final int throttleLimit;

public ConnectionThrottle(int throttleTime)
public ConnectionThrottle(int throttleTime, int throttleLimit)
{
this.throttle = CacheBuilder.newBuilder()
.concurrencyLevel( Runtime.getRuntime().availableProcessors() )
.initialCapacity( 100 )
.expireAfterWrite( throttleTime, TimeUnit.MILLISECONDS )
.build();
.build( new CacheLoader<InetAddress, Integer>()
{
@Override
public Integer load(InetAddress key) throws Exception
{
return 0;
}
} );
this.throttleLimit = throttleLimit;
}

public void unthrottle(InetAddress address)
{
int throttleCount = throttle.getUnchecked( address ) - 1;
throttle.put( address, throttleCount );
}

public boolean throttle(InetAddress address)
{
boolean isThrottled = throttle.getIfPresent( address ) != null;
throttle.put( address, true );
int throttleCount = throttle.getUnchecked( address ) + 1;
throttle.put( address, throttleCount );

return isThrottled;
return throttleCount > throttleLimit;
}
}
2 changes: 2 additions & 0 deletions proxy/src/main/java/net/md_5/bungee/conf/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public class Configuration implements ProxyConfig
private int playerLimit = -1;
private Collection<String> disabledCommands;
private int throttle = 4000;
private int throttleLimit = 3;
private boolean ipForward;
private Favicon favicon;
private int compressionThreshold = 256;
Expand Down Expand Up @@ -89,6 +90,7 @@ public void load()
logPings = adapter.getBoolean( "log_pings", logPings );
playerLimit = adapter.getInt( "player_limit", playerLimit );
throttle = adapter.getInt( "connection_throttle", throttle );
throttleLimit = adapter.getInt( "connection_throttle_limit", throttleLimit );
ipForward = adapter.getBoolean( "ip_forward", ipForward );
compressionThreshold = adapter.getInt( "network_compression_threshold", compressionThreshold );
customServerName = adapter.getString( "custom_server_name", "HexaCord" );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,10 @@ public void done(ProxyPingEvent pingResult, Throwable error)
{
Gson gson = handshake.getProtocolVersion() == ProtocolConstants.MINECRAFT_1_7_2 ? BungeeCord.getInstance().gsonLegacy : BungeeCord.getInstance().gson;
unsafe.sendPacket( new StatusResponse( gson.toJson( pingResult.getResponse() ) ) );
if ( bungee.getConnectionThrottle() != null )
{
bungee.getConnectionThrottle().unthrottle( getAddress().getAddress() );
}
}
};

Expand Down Expand Up @@ -326,11 +330,6 @@ public void handle(Handshake handshake) throws Exception
}
return;
}

if ( bungee.getConnectionThrottle() != null && bungee.getConnectionThrottle().throttle( getAddress().getAddress() ) )
{
disconnect( bungee.getTranslation( "join_throttle_kick", TimeUnit.MILLISECONDS.toSeconds( bungee.getConfig().getThrottle() ) ) );
}
break;
default:
throw new IllegalArgumentException( "Cannot request protocol " + handshake.getRequestedProtocol() );
Expand Down
7 changes: 7 additions & 0 deletions proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.util.AttributeKey;
import io.netty.util.internal.PlatformDependent;
import java.net.InetSocketAddress;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
Expand Down Expand Up @@ -50,6 +51,12 @@ public class PipelineUtils
@Override
protected void initChannel(Channel ch) throws Exception
{
if ( BungeeCord.getInstance().getConnectionThrottle() != null && BungeeCord.getInstance().getConnectionThrottle().throttle( ( (InetSocketAddress) ch.remoteAddress() ).getAddress() ) )
{
ch.close();
return;
}

ListenerInfo listener = ch.attr( LISTENER ).get();

BASE.initChannel( ch );
Expand Down
1 change: 0 additions & 1 deletion proxy/src/main/resources/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,4 @@ total_players=Total players online: {0}
name_too_long=Cannot have username longer than 16 characters
name_invalid=Username contains invalid characters.
ping_cannot_connect=\u00a7c[Bungee] Can't connect to server.
join_throttle_kick=You have connected too fast. You must wait at least {0} seconds between connections.
offline_mode_player=Not authenticated with Minecraft.net
14 changes: 11 additions & 3 deletions proxy/src/test/java/net/md_5/bungee/ThrottleTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class ThrottleTest
@Test
public void testThrottle() throws InterruptedException, UnknownHostException
{
ConnectionThrottle throttle = new ConnectionThrottle( 10 );
ConnectionThrottle throttle = new ConnectionThrottle( 10, 3 );
InetAddress address;

try
Expand All @@ -22,9 +22,17 @@ public void testThrottle() throws InterruptedException, UnknownHostException
address = InetAddress.getByName( null );
}

Assert.assertFalse( "Address should not be throttled", throttle.throttle( address ) );
Assert.assertTrue( "Address should be throttled", throttle.throttle( address ) );
Assert.assertFalse( "Address should not be throttled", throttle.throttle( address ) ); // 1
Assert.assertFalse( "Address should not be throttled", throttle.throttle( address ) ); // 2
Assert.assertFalse( "Address should not be throttled", throttle.throttle( address ) ); // 3
Assert.assertTrue( "Address should be throttled", throttle.throttle( address ) ); // The 3rd one must be throttled, but also increased the count to 4

throttle.unthrottle( address ); // We are back at 3, next attempt will make it 4 and throttle
throttle.unthrottle( address ); // Now we are at 2, will not be throttled
Assert.assertFalse( "Address should not be throttled", throttle.throttle( address ) ); // 3
Assert.assertTrue( "Address should be throttled", throttle.throttle( address ) ); // 4

// Now test expiration
Thread.sleep( 50 );
Assert.assertFalse( "Address should not be throttled", throttle.throttle( address ) );
}
Expand Down

0 comments on commit 1cf1651

Please sign in to comment.