mirror of https://github.com/grpc/grpc-java.git
Implemented Frame Size Negotiation in ALTS for gRPC Java. (#6840)
This commit is contained in:
parent
9ead606b84
commit
cfe73eb484
|
|
@ -82,6 +82,7 @@ class AltsHandshakerClient {
|
|||
startClientReq.addTargetIdentitiesBuilder().setServiceAccount(serviceAccount);
|
||||
}
|
||||
}
|
||||
startClientReq.setMaxFrameSize(AltsTsiFrameProtector.getMaxFrameSize());
|
||||
req.setClientStart(startClientReq);
|
||||
}
|
||||
|
||||
|
|
@ -97,6 +98,7 @@ class AltsHandshakerClient {
|
|||
if (handshakerOptions.getRpcProtocolVersions() != null) {
|
||||
startServerReq.setRpcVersions(handshakerOptions.getRpcProtocolVersions());
|
||||
}
|
||||
startServerReq.setMaxFrameSize(AltsTsiFrameProtector.getMaxFrameSize());
|
||||
req.setServerStart(startServerReq);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,9 +33,10 @@ public final class AltsTsiFrameProtector implements TsiFrameProtector {
|
|||
private static final int HEADER_TYPE_FIELD_BYTES = 4;
|
||||
private static final int HEADER_BYTES = HEADER_LEN_FIELD_BYTES + HEADER_TYPE_FIELD_BYTES;
|
||||
private static final int HEADER_TYPE_DEFAULT = 6;
|
||||
// Total frame size including full header and tag.
|
||||
private static final int MAX_ALLOWED_FRAME_BYTES = 16 * 1024;
|
||||
private static final int LIMIT_MAX_ALLOWED_FRAME_BYTES = 1024 * 1024;
|
||||
private static final int LIMIT_MAX_ALLOWED_FRAME_SIZE = 1024 * 1024;
|
||||
// Frame size negotiation extends frame size range to [MIN_FRAME_SIZE, MAX_FRAME_SIZE].
|
||||
private static final int MIN_FRAME_SIZE = 16 * 1024;
|
||||
private static final int MAX_FRAME_SIZE = 128 * 1024;
|
||||
|
||||
private final Protector protector;
|
||||
private final Unprotector unprotector;
|
||||
|
|
@ -44,7 +45,7 @@ public final class AltsTsiFrameProtector implements TsiFrameProtector {
|
|||
public AltsTsiFrameProtector(
|
||||
int maxProtectedFrameBytes, ChannelCrypterNetty crypter, ByteBufAllocator alloc) {
|
||||
checkArgument(maxProtectedFrameBytes > HEADER_BYTES + crypter.getSuffixLength());
|
||||
maxProtectedFrameBytes = Math.min(LIMIT_MAX_ALLOWED_FRAME_BYTES, maxProtectedFrameBytes);
|
||||
maxProtectedFrameBytes = Math.min(LIMIT_MAX_ALLOWED_FRAME_SIZE, maxProtectedFrameBytes);
|
||||
protector = new Protector(maxProtectedFrameBytes, crypter);
|
||||
unprotector = new Unprotector(crypter, alloc);
|
||||
}
|
||||
|
|
@ -65,12 +66,16 @@ public final class AltsTsiFrameProtector implements TsiFrameProtector {
|
|||
return HEADER_TYPE_DEFAULT;
|
||||
}
|
||||
|
||||
public static int getMaxAllowedFrameBytes() {
|
||||
return MAX_ALLOWED_FRAME_BYTES;
|
||||
static int getLimitMaxAllowedFrameSize() {
|
||||
return LIMIT_MAX_ALLOWED_FRAME_SIZE;
|
||||
}
|
||||
|
||||
static int getLimitMaxAllowedFrameBytes() {
|
||||
return LIMIT_MAX_ALLOWED_FRAME_BYTES;
|
||||
public static int getMinFrameSize() {
|
||||
return MIN_FRAME_SIZE;
|
||||
}
|
||||
|
||||
public static int getMaxFrameSize() {
|
||||
return MAX_FRAME_SIZE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -262,7 +267,7 @@ public final class AltsTsiFrameProtector implements TsiFrameProtector {
|
|||
checkArgument(
|
||||
requiredProtectedBytes >= suffixBytes, "Invalid header field: frame size too small");
|
||||
checkArgument(
|
||||
requiredProtectedBytes <= LIMIT_MAX_ALLOWED_FRAME_BYTES - HEADER_BYTES,
|
||||
requiredProtectedBytes <= LIMIT_MAX_ALLOWED_FRAME_SIZE - HEADER_BYTES,
|
||||
"Invalid header field: frame size too large");
|
||||
int frameType = header.readIntLE();
|
||||
checkArgument(frameType == HEADER_TYPE_DEFAULT, "Invalid header field: frame type");
|
||||
|
|
|
|||
|
|
@ -26,11 +26,15 @@ import java.nio.ByteBuffer;
|
|||
import java.security.GeneralSecurityException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Negotiates a grpc channel key to be used by the TsiFrameProtector, using ALTs handshaker service.
|
||||
*/
|
||||
public final class AltsTsiHandshaker implements TsiHandshaker {
|
||||
private static final Logger logger = Logger.getLogger(AltsTsiHandshaker.class.getName());
|
||||
|
||||
public static final String TSI_SERVICE_ACCOUNT_PEER_PROPERTY = "service_account";
|
||||
|
||||
private final boolean isClient;
|
||||
|
|
@ -178,6 +182,14 @@ public final class AltsTsiHandshaker implements TsiHandshaker {
|
|||
byte[] key = handshaker.getKey();
|
||||
Preconditions.checkState(key.length == AltsChannelCrypter.getKeyLength(), "Bad key length.");
|
||||
|
||||
// Frame size negotiation is not performed if the peer does not send max frame size (e.g. peer
|
||||
// is gRPC Go or peer uses an old binary).
|
||||
int peerMaxFrameSize = handshaker.getResult().getMaxFrameSize();
|
||||
if (peerMaxFrameSize != 0) {
|
||||
maxFrameSize = Math.min(peerMaxFrameSize, AltsTsiFrameProtector.getMaxFrameSize());
|
||||
maxFrameSize = Math.max(AltsTsiFrameProtector.getMinFrameSize(), maxFrameSize);
|
||||
}
|
||||
logger.log(Level.INFO, "Maximum frame size value is " + maxFrameSize);
|
||||
return new AltsTsiFrameProtector(maxFrameSize, new AltsChannelCrypter(key, isClient), alloc);
|
||||
}
|
||||
|
||||
|
|
@ -190,7 +202,7 @@ public final class AltsTsiHandshaker implements TsiHandshaker {
|
|||
*/
|
||||
@Override
|
||||
public TsiFrameProtector createFrameProtector(ByteBufAllocator alloc) {
|
||||
return createFrameProtector(AltsTsiFrameProtector.getMaxAllowedFrameBytes(), alloc);
|
||||
return createFrameProtector(AltsTsiFrameProtector.getMinFrameSize(), alloc);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ public class AltsHandshakerClientTest {
|
|||
.setTargetName(TEST_TARGET_NAME)
|
||||
.addTargetIdentities(
|
||||
Identity.newBuilder().setServiceAccount(TEST_TARGET_SERVICE_ACCOUNT))
|
||||
.setMaxFrameSize(AltsTsiFrameProtector.getMaxFrameSize())
|
||||
.build())
|
||||
.build();
|
||||
verify(mockStub).send(req);
|
||||
|
|
@ -133,6 +134,22 @@ public class AltsHandshakerClientTest {
|
|||
ByteBuffer inBytes = ByteBuffer.allocate(IN_BYTES_SIZE);
|
||||
ByteBuffer outFrame = handshaker.startServerHandshake(inBytes);
|
||||
|
||||
HandshakerReq req =
|
||||
HandshakerReq.newBuilder()
|
||||
.setServerStart(
|
||||
StartServerHandshakeReq.newBuilder()
|
||||
.addApplicationProtocols(AltsHandshakerClient.getApplicationProtocol())
|
||||
.putHandshakeParameters(
|
||||
HandshakeProtocol.ALTS.getNumber(),
|
||||
ServerHandshakeParameters.newBuilder()
|
||||
.addRecordProtocols(AltsHandshakerClient.getRecordProtocol())
|
||||
.build())
|
||||
.setInBytes(ByteString.copyFrom(ByteBuffer.allocate(IN_BYTES_SIZE)))
|
||||
.setMaxFrameSize(AltsTsiFrameProtector.getMaxFrameSize())
|
||||
.build())
|
||||
.build();
|
||||
verify(mockStub).send(req);
|
||||
|
||||
assertEquals(ByteString.copyFrom(outFrame), MockAltsHandshakerResp.getOutFrame());
|
||||
assertFalse(handshaker.isFinished());
|
||||
assertNull(handshaker.getResult());
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ public class AltsTsiFrameProtectorTest {
|
|||
getDirectBuffer(
|
||||
AltsTsiFrameProtector.getHeaderBytes() + FakeChannelCrypter.getTagBytes(), ref);
|
||||
in.writeIntLE(
|
||||
AltsTsiFrameProtector.getLimitMaxAllowedFrameBytes()
|
||||
AltsTsiFrameProtector.getLimitMaxAllowedFrameSize()
|
||||
- AltsTsiFrameProtector.getHeaderLenFieldBytes()
|
||||
+ 1);
|
||||
in.writeIntLE(6);
|
||||
|
|
@ -206,7 +206,7 @@ public class AltsTsiFrameProtectorTest {
|
|||
getDirectBuffer(
|
||||
AltsTsiFrameProtector.getHeaderBytes() + FakeChannelCrypter.getTagBytes(), ref);
|
||||
in.writeIntLE(
|
||||
AltsTsiFrameProtector.getLimitMaxAllowedFrameBytes()
|
||||
AltsTsiFrameProtector.getLimitMaxAllowedFrameSize()
|
||||
- AltsTsiFrameProtector.getHeaderLenFieldBytes());
|
||||
in.writeIntLE(6);
|
||||
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@ public class FakeTsiHandshaker implements TsiHandshaker {
|
|||
|
||||
@Override
|
||||
public TsiFrameProtector createFrameProtector(ByteBufAllocator alloc) {
|
||||
return createFrameProtector(AltsTsiFrameProtector.getMaxAllowedFrameBytes(), alloc);
|
||||
return createFrameProtector(AltsTsiFrameProtector.getMinFrameSize(), alloc);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
Loading…
Reference in New Issue