From 146a3d75f09da974928d70cbbccb69311174d6dc Mon Sep 17 00:00:00 2001 From: Joran Dirk Greef Date: Wed, 15 Sep 2021 13:57:40 +0200 Subject: [PATCH] VSR: Fix liveness issue for misdirected reply messages We now also ignore unexpected commands in the Replica's on_message() handler as we were doing for the Client, and we use an exhaustive switch, which would also have been better in the first place. Reported-by: @ThreeFx Refs: #9 --- src/vsr/client.zig | 10 +++++----- src/vsr/replica.zig | 14 +++++++++++++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/vsr/client.zig b/src/vsr/client.zig index 9b2ca57..7017adc 100644 --- a/src/vsr/client.zig +++ b/src/vsr/client.zig @@ -136,11 +136,11 @@ pub fn Client(comptime StateMachine: type, comptime MessageBus: type) type { .reply => self.on_reply(message), .eviction => self.on_eviction(message), else => { - // This could be because of a misdirected packet. - log.warn( - "{}: on_message: unexpected command {}", - .{ self.id, message.header.command }, - ); + log.warn("{}: on_message: ignoring misdirected {s} message", .{ + self.id, + @tagName(message.header.command), + }); + return; }, } } diff --git a/src/vsr/replica.zig b/src/vsr/replica.zig index 1185ea4..a3338cb 100644 --- a/src/vsr/replica.zig +++ b/src/vsr/replica.zig @@ -456,6 +456,9 @@ pub fn Replica( return; } + // No client or replica should ever send a .reserved message. + assert(message.header.command != .reserved); + if (message.header.cluster != self.cluster) { log.warn("{}: on_message: wrong cluster (cluster must be {} not {})", .{ self.replica, @@ -485,12 +488,21 @@ pub fn Replica( .do_view_change => self.on_do_view_change(message), .start_view => self.on_start_view(message), .recovery => self.on_recovery(message), + .recovery_response => return, // TODO .request_start_view => self.on_request_start_view(message), .request_prepare => self.on_request_prepare(message), .request_headers => self.on_request_headers(message), .headers => self.on_headers(message), .nack_prepare => self.on_nack_prepare(message), - else => unreachable, + // A replica should never handle misdirected messages intended for a client: + .eviction, .reply => { + log.warn("{}: on_message: ignoring misdirected {s} message", .{ + self.replica, + @tagName(message.header.command), + }); + return; + }, + .reserved => unreachable, } if (self.loopback_queue) |loopback_message| {