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

Commit

Permalink
Merge branch 'SpigotMC-master'
Browse files Browse the repository at this point in the history
Closes #20
  • Loading branch information
Zartec committed May 15, 2016
2 parents 1e7790d + 9ab51c0 commit 6178e75
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 30 deletions.
20 changes: 16 additions & 4 deletions protocol/src/main/java/net/md_5/bungee/protocol/DefinedPacket.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ public abstract class DefinedPacket

public static void writeString(String s, ByteBuf buf)
{
Preconditions.checkArgument( s.length() <= Short.MAX_VALUE, "Cannot send string longer than Short.MAX_VALUE (got %s characters)", s.length() );
if ( s.length() > Short.MAX_VALUE )
{
throw new OverflowPacketException( String.format( "Cannot send string longer than Short.MAX_VALUE (got %s characters)", s.length() ) );
}

byte[] b = s.getBytes( Charsets.UTF_8 );
writeVarInt( b.length, buf );
Expand All @@ -25,7 +28,10 @@ public static void writeString(String s, ByteBuf buf)
public static String readString(ByteBuf buf)
{
int len = readVarInt( buf );
Preconditions.checkArgument( len <= Short.MAX_VALUE, "Cannot receive string longer than Short.MAX_VALUE (got %s characters)", len );
if ( len > Short.MAX_VALUE )
{
throw new OverflowPacketException( String.format( "Cannot receive string longer than Short.MAX_VALUE (got %s characters)", len ) );
}

byte[] b = new byte[ len ];
buf.readBytes( b );
Expand All @@ -35,7 +41,10 @@ public static String readString(ByteBuf buf)

public static void writeArray(byte[] b, ByteBuf buf)
{
Preconditions.checkArgument( b.length <= Short.MAX_VALUE, "Cannot send byte array longer than Short.MAX_VALUE (got %s bytes)", b.length );
if ( b.length > Short.MAX_VALUE )
{
throw new OverflowPacketException( String.format( "Cannot send byte array longer than Short.MAX_VALUE (got %s bytes)", b.length ) );
}
writeVarInt( b.length, buf );
buf.writeBytes( b );
}
Expand All @@ -48,7 +57,10 @@ public static byte[] readArray(ByteBuf buf)
public static byte[] readArray(ByteBuf buf, int limit)
{
int len = readVarInt( buf );
Preconditions.checkArgument( len <= limit, "Cannot receive byte array longer than %s (got %s bytes)", limit, len );
if ( len > limit )
{
throw new OverflowPacketException( String.format( "Cannot receive byte array longer than %s (got %s bytes)", limit, len ) );
}
byte[] ret = new byte[ len ];
buf.readBytes( ret );
return ret;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package net.md_5.bungee.protocol;

public class OverflowPacketException extends RuntimeException
{

public OverflowPacketException(String message)
{
super( message );
}
}
28 changes: 20 additions & 8 deletions protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.md_5.bungee.protocol;

import com.google.common.base.Preconditions;
import com.google.common.collect.Iterables;
import gnu.trove.map.TIntObjectMap;
import gnu.trove.map.TObjectIntMap;
import gnu.trove.map.hash.TIntObjectHashMap;
Expand Down Expand Up @@ -223,8 +224,8 @@ public enum Protocol
/*========================================================================*/
public static final int MAX_PACKET_ID = 0xFF;
/*========================================================================*/
public final DirectionData TO_SERVER = new DirectionData( ProtocolConstants.Direction.TO_SERVER );
public final DirectionData TO_CLIENT = new DirectionData( ProtocolConstants.Direction.TO_CLIENT );
public final DirectionData TO_SERVER = new DirectionData(this, ProtocolConstants.Direction.TO_SERVER );
public final DirectionData TO_CLIENT = new DirectionData(this, ProtocolConstants.Direction.TO_CLIENT );

@RequiredArgsConstructor
private static class ProtocolData {
Expand Down Expand Up @@ -252,6 +253,7 @@ private static ProtocolMapping map(int protocol, int id, boolean inherit) {
public static class DirectionData
{

private final Protocol protocolPhase;
private final TIntObjectMap<ProtocolData> protocols = new TIntObjectHashMap<>();
{
for ( int protocol : ProtocolConstants.SUPPORTED_VERSION_IDS )
Expand All @@ -277,12 +279,22 @@ public static class DirectionData
@Getter
private final ProtocolConstants.Direction direction;

public final DefinedPacket createPacket(int id, int protocol)
private ProtocolData getProtocolData(int version)
{
ProtocolData protocolData = protocols.get( protocol );
ProtocolData protocol = protocols.get( version );
if ( protocol == null && ( protocolPhase == Protocol.HANDSHAKE || protocolPhase == Protocol.STATUS ) )
{
protocol = Iterables.getFirst( protocols.valueCollection(), null );
}
return protocol;
}

public final DefinedPacket createPacket(int id, int version)
{
ProtocolData protocolData = getProtocolData( version );
if (protocolData == null)
{
throw new BadPacketException( "Unsupported protocol" );
throw new BadPacketException( "Unsupported protocol version" );
}
if ( id > MAX_PACKET_ID )
{
Expand Down Expand Up @@ -336,13 +348,13 @@ protected final void registerPacket(Class<? extends DefinedPacket> packetClass,
}
}

final int getId(Class<? extends DefinedPacket> packet, int protocol)
final int getId(Class<? extends DefinedPacket> packet, int version)
{

ProtocolData protocolData = protocols.get( protocol );
ProtocolData protocolData = getProtocolData( version );
if (protocolData == null)
{
throw new BadPacketException( "Unsupported protocol" );
throw new BadPacketException( "Unsupported protocol version" );
}
Preconditions.checkArgument( protocolData.packetMap.containsKey( packet ), "Cannot get ID for packet " + packet );

Expand Down
13 changes: 5 additions & 8 deletions proxy/src/main/java/net/md_5/bungee/ConnectionThrottle.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,22 @@
public class ConnectionThrottle
{

private final int throttleTime;
private final Cache<InetAddress, Long> throttle;
private final Cache<InetAddress, Boolean> throttle;

public ConnectionThrottle(int throttleTime)
{
this.throttleTime = throttleTime;
this.throttle = CacheBuilder.newBuilder()
.concurrencyLevel( Runtime.getRuntime().availableProcessors() )
.initialCapacity( 100 )
.expireAfterAccess( throttleTime, TimeUnit.MILLISECONDS )
.expireAfterWrite( throttleTime, TimeUnit.MILLISECONDS )
.build();
}

public boolean throttle(InetAddress address)
{
Long value = throttle.getIfPresent( address );
long currentTime = System.currentTimeMillis();
boolean isThrottled = throttle.getIfPresent( address ) != null;
throttle.put( address, true );

throttle.put( address, currentTime );
return value != null && currentTime - value < throttleTime;
return isThrottled;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,12 @@ public void handle(Handshake handshake) throws Exception
thisState = State.USERNAME;
ch.setProtocol( Protocol.LOGIN );

if ( !ProtocolConstants.SUPPORTED_VERSION_IDS.contains( handshake.getProtocolVersion() ) )
{
disconnect( bungee.getTranslation( "outdated_server" ) );
return;
}

if ( bungee.getConnectionThrottle() != null && bungee.getConnectionThrottle().throttle( getAddress().getAddress() ) )
{
disconnect( bungee.getTranslation( "join_throttle_kick", TimeUnit.MILLISECONDS.toSeconds( bungee.getConfig().getThrottle() ) ) );
Expand All @@ -309,12 +315,6 @@ public void handle(LoginRequest loginRequest) throws Exception
Preconditions.checkState( thisState == State.USERNAME, "Not expecting USERNAME" );
this.loginRequest = loginRequest;

if ( !ProtocolConstants.SUPPORTED_VERSION_IDS.contains( handshake.getProtocolVersion() ) )
{
disconnect( bungee.getTranslation( "outdated_server" ) );
return;
}

if ( getName().contains( "." ) )
{
disconnect( bungee.getTranslation( "name_invalid" ) );
Expand Down
9 changes: 7 additions & 2 deletions proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import net.md_5.bungee.connection.InitialHandler;
import net.md_5.bungee.connection.PingHandler;
import net.md_5.bungee.protocol.BadPacketException;
import net.md_5.bungee.protocol.OverflowPacketException;

/**
* This class is a primitive wrapper for {@link PacketHandler} instances tied to
Expand Down Expand Up @@ -104,8 +105,12 @@ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws E
{
handler, cause.getCause().getMessage()
} );

cause.printStackTrace();
} else if ( cause instanceof DecoderException && cause.getCause() instanceof OverflowPacketException )
{
ProxyServer.getInstance().getLogger().log( Level.WARNING, "{0} - overflow in packet detected! {1}", new Object[]
{
handler, cause.getCause().getMessage()
} );
} else if ( cause instanceof IOException )
{
ProxyServer.getInstance().getLogger().log( Level.WARNING, "{0} - IOException: {1}", new Object[]
Expand Down
4 changes: 2 additions & 2 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( 5 );
ConnectionThrottle throttle = new ConnectionThrottle( 10 );
InetAddress address;

try
Expand All @@ -25,7 +25,7 @@ public void testThrottle() throws InterruptedException, UnknownHostException
Assert.assertFalse( "Address should not be throttled", throttle.throttle( address ) );
Assert.assertTrue( "Address should be throttled", throttle.throttle( address ) );

Thread.sleep( 15 );
Thread.sleep( 50 );
Assert.assertFalse( "Address should not be throttled", throttle.throttle( address ) );
}
}

0 comments on commit 6178e75

Please sign in to comment.