From bc7f567467812187f7df827737bfc4f9ef74e12e Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 11 Feb 2019 11:02:28 -0600 Subject: [PATCH] msg/async/ProtocolV2: refuse incoming reconnect attempt intended for someone else The same scenario that was possible on client_ident is also possible for reconnect: on the accepting side we recognized the client_addrs but the client is trying to reach someone else. Since the cookie is a random 64-bit value it is unlikely, but still possible, that we will match an existing session that is not for the client. Signed-off-by: Sage Weil --- doc/dev/msgr2.rst | 1 + src/msg/async/ProtocolV2.cc | 32 +++++++++++++++++++++++--------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/doc/dev/msgr2.rst b/doc/dev/msgr2.rst index 181f347f33f..08d04ee85b9 100644 --- a/doc/dev/msgr2.rst +++ b/doc/dev/msgr2.rst @@ -295,6 +295,7 @@ an established session. __le32 num_addrs entity_addr_t * num_addrs + entity_addr_t target entity addr __le64 cookie __le64 id (of name.id, e.g., osd.123 -> 123) __le64 global_seq diff --git a/src/msg/async/ProtocolV2.cc b/src/msg/async/ProtocolV2.cc index 4fca73d544a..d6ecc44f763 100644 --- a/src/msg/async/ProtocolV2.cc +++ b/src/msg/async/ProtocolV2.cc @@ -342,7 +342,9 @@ struct ServerIdentFrame }; struct ReconnectFrame - : public SignedEncryptedFrame(); } - inline uint64_t &cookie() { return get_val<1>(); } - inline int64_t &gid() { return get_val<2>(); } - inline uint64_t &global_seq() { return get_val<3>(); } - inline uint64_t &connect_seq() { return get_val<4>(); } - inline uint64_t &supported_features() { return get_val<5>(); } - inline uint64_t &required_features() { return get_val<6>(); } - inline uint64_t &msg_seq() { return get_val<7>(); } + inline entity_addr_t &target_addr() { return get_val<1>(); } + inline uint64_t &cookie() { return get_val<2>(); } + inline int64_t &gid() { return get_val<3>(); } + inline uint64_t &global_seq() { return get_val<4>(); } + inline uint64_t &connect_seq() { return get_val<5>(); } + inline uint64_t &supported_features() { return get_val<6>(); } + inline uint64_t &required_features() { return get_val<7>(); } + inline uint64_t &msg_seq() { return get_val<8>(); } }; struct ResetFrame : public Frame { @@ -2255,7 +2258,9 @@ CtPtr ProtocolV2::send_client_ident() { CtPtr ProtocolV2::send_reconnect() { ldout(cct, 20) << __func__ << dendl; - ReconnectFrame reconnect(this, messenger->get_myaddrs(), cookie, + ReconnectFrame reconnect(this, messenger->get_myaddrs(), + connection->target_addr, + cookie, messenger->get_myname().num(), global_seq, connect_seq, @@ -2593,12 +2598,21 @@ CtPtr ProtocolV2::handle_reconnect(char *payload, uint32_t length) { ldout(cct, 5) << __func__ << " received reconnect: cookie=" << reconnect.cookie() + << " target_addr=" << reconnect.target_addr() << " gid=" << reconnect.gid() << " gs=" << reconnect.global_seq() << " cs=" << reconnect.connect_seq() << " ms=" << reconnect.msg_seq() << dendl; + if (!messenger->get_myaddrs().contains(reconnect.target_addr())) { + ldout(cct,5) << __func__ << " peer is trying to reach " + << reconnect.target_addr() + << " which is not us (" << messenger->get_myaddrs() << ")" + << dendl; + return _fault(); + } + // Should we check if one of the ident.addrs match connection->target_addr // as we do in ProtocolV1? connection->set_peer_addrs(reconnect.addrs()); -- 2.39.5