Reply with error status on receiving message with incorrect preamble

Change-Id: I0d17dc74c817546f221fbcade1d5642c8f29b0fe
This commit is contained in:
Madan Jampani 2016-04-01 15:18:25 -07:00 committed by Gerrit Code Review
parent 33d81c6ba3
commit b825aebe03
4 changed files with 38 additions and 17 deletions

View File

@ -49,4 +49,10 @@ public class MessagingException extends IOException {
*/ */
public static class RemoteHandlerFailure extends MessagingException { public static class RemoteHandlerFailure extends MessagingException {
} }
/**
* Exception indicating failure due to invalid message strucuture such as an incorrect preamble.
*/
public static class ProcotolException extends MessagingException {
}
} }

View File

@ -42,24 +42,31 @@ public final class InternalMessage {
/** /**
* Response status signifying an exception handling the message. * Response status signifying an exception handling the message.
*/ */
ERROR_HANDLER_EXCEPTION ERROR_HANDLER_EXCEPTION,
/**
* Reponse status signifying invalid message structure.
*/
PROTOCOL_EXCEPTION
// NOTE: For backwards compatibility it important that new enum constants // NOTE: For backwards compatibility it important that new enum constants
// be appended. // be appended.
// FIXME: We should remove this restriction in the future. // FIXME: We should remove this restriction in the future.
} }
private final int preamble;
private final long id; private final long id;
private final Endpoint sender; private final Endpoint sender;
private final String type; private final String type;
private final byte[] payload; private final byte[] payload;
private final Status status; private final Status status;
public InternalMessage(long id, Endpoint sender, String type, byte[] payload) { public InternalMessage(int preamble, long id, Endpoint sender, String type, byte[] payload) {
this(id, sender, type, payload, Status.OK); this(preamble, id, sender, type, payload, Status.OK);
} }
public InternalMessage(long id, Endpoint sender, String type, byte[] payload, Status status) { public InternalMessage(int preamble, long id, Endpoint sender, String type, byte[] payload, Status status) {
this.preamble = preamble;
this.id = id; this.id = id;
this.sender = sender; this.sender = sender;
this.type = type; this.type = type;
@ -67,6 +74,10 @@ public final class InternalMessage {
this.status = status; this.status = status;
} }
public int preamble() {
return preamble;
}
public long id() { public long id() {
return id; return id;
} }

View File

@ -39,7 +39,6 @@ public class MessageDecoder extends ReplayingDecoder<DecoderState> {
private final Logger log = LoggerFactory.getLogger(getClass()); private final Logger log = LoggerFactory.getLogger(getClass());
private final int correctPreamble;
private long messageId; private long messageId;
private int preamble; private int preamble;
private Version ipVersion; private Version ipVersion;
@ -50,9 +49,8 @@ public class MessageDecoder extends ReplayingDecoder<DecoderState> {
private Status status; private Status status;
private int contentLength; private int contentLength;
public MessageDecoder(int correctPreamble) { public MessageDecoder() {
super(DecoderState.READ_MESSAGE_PREAMBLE); super(DecoderState.READ_MESSAGE_PREAMBLE);
this.correctPreamble = correctPreamble;
} }
@Override @Override
@ -65,9 +63,6 @@ public class MessageDecoder extends ReplayingDecoder<DecoderState> {
switch (state()) { switch (state()) {
case READ_MESSAGE_PREAMBLE: case READ_MESSAGE_PREAMBLE:
preamble = buffer.readInt(); preamble = buffer.readInt();
if (preamble != correctPreamble) {
throw new IllegalStateException("This message had an incorrect preamble.");
}
checkpoint(DecoderState.READ_MESSAGE_ID); checkpoint(DecoderState.READ_MESSAGE_ID);
case READ_MESSAGE_ID: case READ_MESSAGE_ID:
messageId = buffer.readLong(); messageId = buffer.readLong();
@ -106,7 +101,8 @@ public class MessageDecoder extends ReplayingDecoder<DecoderState> {
} else { } else {
payload = new byte[0]; payload = new byte[0];
} }
InternalMessage message = new InternalMessage(messageId, InternalMessage message = new InternalMessage(preamble,
messageId,
new Endpoint(senderIp, senderPort), new Endpoint(senderIp, senderPort),
messageType, messageType,
payload, payload,

View File

@ -217,7 +217,8 @@ public class NettyMessagingManager implements MessagingService {
@Override @Override
public CompletableFuture<Void> sendAsync(Endpoint ep, String type, byte[] payload) { public CompletableFuture<Void> sendAsync(Endpoint ep, String type, byte[] payload) {
checkPermission(CLUSTER_WRITE); checkPermission(CLUSTER_WRITE);
InternalMessage message = new InternalMessage(messageIdGenerator.incrementAndGet(), InternalMessage message = new InternalMessage(preamble,
messageIdGenerator.incrementAndGet(),
localEp, localEp,
type, type,
payload); payload);
@ -263,7 +264,7 @@ public class NettyMessagingManager implements MessagingService {
Callback callback = new Callback(response, executor); Callback callback = new Callback(response, executor);
Long messageId = messageIdGenerator.incrementAndGet(); Long messageId = messageIdGenerator.incrementAndGet();
callbacks.put(messageId, callback); callbacks.put(messageId, callback);
InternalMessage message = new InternalMessage(messageId, localEp, type, payload); InternalMessage message = new InternalMessage(preamble, messageId, localEp, type, payload);
return sendAsync(ep, message).whenComplete((r, e) -> { return sendAsync(ep, message).whenComplete((r, e) -> {
if (e != null) { if (e != null) {
callbacks.invalidate(messageId); callbacks.invalidate(messageId);
@ -425,7 +426,7 @@ public class NettyMessagingManager implements MessagingService {
channel.pipeline().addLast("ssl", new io.netty.handler.ssl.SslHandler(serverSslEngine)) channel.pipeline().addLast("ssl", new io.netty.handler.ssl.SslHandler(serverSslEngine))
.addLast("encoder", encoder) .addLast("encoder", encoder)
.addLast("decoder", new MessageDecoder(preamble)) .addLast("decoder", new MessageDecoder())
.addLast("handler", dispatcher); .addLast("handler", dispatcher);
} }
} }
@ -459,7 +460,7 @@ public class NettyMessagingManager implements MessagingService {
channel.pipeline().addLast("ssl", new io.netty.handler.ssl.SslHandler(clientSslEngine)) channel.pipeline().addLast("ssl", new io.netty.handler.ssl.SslHandler(clientSslEngine))
.addLast("encoder", encoder) .addLast("encoder", encoder)
.addLast("decoder", new MessageDecoder(preamble)) .addLast("decoder", new MessageDecoder())
.addLast("handler", dispatcher); .addLast("handler", dispatcher);
} }
} }
@ -473,7 +474,7 @@ public class NettyMessagingManager implements MessagingService {
protected void initChannel(SocketChannel channel) throws Exception { protected void initChannel(SocketChannel channel) throws Exception {
channel.pipeline() channel.pipeline()
.addLast("encoder", encoder) .addLast("encoder", encoder)
.addLast("decoder", new MessageDecoder(preamble)) .addLast("decoder", new MessageDecoder())
.addLast("handler", dispatcher); .addLast("handler", dispatcher);
} }
} }
@ -497,6 +498,10 @@ public class NettyMessagingManager implements MessagingService {
} }
} }
private void dispatchLocally(InternalMessage message) throws IOException { private void dispatchLocally(InternalMessage message) throws IOException {
if (message.preamble() != preamble) {
log.debug("Received {} with invalid preamble from {}", message.type(), message.sender());
sendReply(message, Status.PROTOCOL_EXCEPTION, Optional.empty());
}
String type = message.type(); String type = message.type();
if (REPLY_MESSAGE_TYPE.equals(type)) { if (REPLY_MESSAGE_TYPE.equals(type)) {
try { try {
@ -509,6 +514,8 @@ public class NettyMessagingManager implements MessagingService {
callback.completeExceptionally(new MessagingException.NoRemoteHandler()); callback.completeExceptionally(new MessagingException.NoRemoteHandler());
} else if (message.status() == Status.ERROR_HANDLER_EXCEPTION) { } else if (message.status() == Status.ERROR_HANDLER_EXCEPTION) {
callback.completeExceptionally(new MessagingException.RemoteHandlerFailure()); callback.completeExceptionally(new MessagingException.RemoteHandlerFailure());
} else if (message.status() == Status.PROTOCOL_EXCEPTION) {
callback.completeExceptionally(new MessagingException.ProcotolException());
} }
} else { } else {
log.debug("Received a reply for message id:[{}]. " log.debug("Received a reply for message id:[{}]. "
@ -530,7 +537,8 @@ public class NettyMessagingManager implements MessagingService {
} }
private void sendReply(InternalMessage message, Status status, Optional<byte[]> responsePayload) { private void sendReply(InternalMessage message, Status status, Optional<byte[]> responsePayload) {
InternalMessage response = new InternalMessage(message.id(), InternalMessage response = new InternalMessage(preamble,
message.id(),
localEp, localEp,
REPLY_MESSAGE_TYPE, REPLY_MESSAGE_TYPE,
responsePayload.orElse(new byte[0]), responsePayload.orElse(new byte[0]),