]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
msg/async/ProtocolV2: refuse incoming reconnect attempt intended for someone else
authorSage Weil <sage@redhat.com>
Mon, 11 Feb 2019 17:02:28 +0000 (11:02 -0600)
committerSage Weil <sage@redhat.com>
Mon, 11 Feb 2019 17:02:28 +0000 (11:02 -0600)
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 <sage@redhat.com>
doc/dev/msgr2.rst
src/msg/async/ProtocolV2.cc

index 181f347f33f625010d70c86b7f172aa18fda6471..08d04ee85b9d0e34efd1706aa4f164121ccb82ae 100644 (file)
@@ -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
index 4fca73d544a38b16d5024a86e08e9dea2f9e9463..d6ecc44f7635fcbf4dc89a87a34292e35e9a527b 100644 (file)
@@ -342,7 +342,9 @@ struct ServerIdentFrame
 };
 
 struct ReconnectFrame
-    : public SignedEncryptedFrame<ReconnectFrame, entity_addrvec_t, uint64_t,
+    : public SignedEncryptedFrame<ReconnectFrame, entity_addrvec_t,
+                                 entity_addr_t,
+                                 uint64_t,
                                  int64_t,
                                   uint64_t, uint64_t,
                                  uint64_t, uint64_t,
@@ -351,13 +353,14 @@ struct ReconnectFrame
   using SignedEncryptedFrame::SignedEncryptedFrame;
 
   inline entity_addrvec_t &addrs() { return get_val<0>(); }
-  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<ResetFrame> {
@@ -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());