From 51067350ad449548dbed07ad972524794b1722c8 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 31 Jan 2019 16:52:09 -0600 Subject: [PATCH] msg/async/ProtocolV2: respect policy.resetcheck on cookie==0 It's possible the accepting end knows the cookie but the connecting end does not if the fault happens before it receives server_ident. If the next connection attempt is in the other direction, we need to avoid a reset or the queued messages at the first site will get lost. Fixes: http://tracker.ceph.com/issues/38118 Signed-off-by: Sage Weil --- src/msg/async/ProtocolV2.cc | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/msg/async/ProtocolV2.cc b/src/msg/async/ProtocolV2.cc index b7d413e84788..16ed5163b5a5 100644 --- a/src/msg/async/ProtocolV2.cc +++ b/src/msg/async/ProtocolV2.cc @@ -2701,15 +2701,29 @@ CtPtr ProtocolV2::handle_reconnect(char *payload, uint32_t length) { return WRITE(bl, "session retry", read_frame); } - if (!exproto->cookie) { - // server connection was reseted, reset client - ldout(cct, 5) << __func__ << " no cookie set, reseting client" << dendl; - return WRITE(bl, "session reset", read_frame); - } else if (exproto->cookie != reconnect.cookie()) { - ldout(cct, 5) << __func__ << " cookie mismatch sc=" << exproto->cookie - << " cc=" << reconnect.cookie() << ", reseting client" - << dendl; - return WRITE(bl, "session reset", read_frame); + if (connection->policy.resetcheck) { + if (!exproto->cookie) { + // server connection was reseted, reset client + ldout(cct, 5) << __func__ << " no cookie set, reseting client" << dendl; + return WRITE(bl, "session reset", read_frame); + } else if (exproto->cookie != reconnect.cookie()) { + ldout(cct, 5) << __func__ << " cookie mismatch sc=" << exproto->cookie + << " cc=" << reconnect.cookie() << ", reseting client" + << dendl; + return WRITE(bl, "session reset", read_frame); + } + } else { + if (exproto->cookie == 0) { + // this happens when: + // - a connects to b + // - a sends client_ident + // - b gets client_ident, sends server_ident and sets cookie X + // - connection fault + // - b reconnects to a with cookie X, connect_seq=1 + // - a has cookie==0 + ldout(cct, 5) << __func__ << " no cookie set, setting" << dendl; + exproto->cookie = reconnect.cookie(); + } } if (exproto->peer_global_seq > reconnect.global_seq()) { -- 2.47.3