]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
msg/async: identify client using any: addr
authorSage Weil <sage@redhat.com>
Mon, 28 Jan 2019 08:15:23 +0000 (02:15 -0600)
committerSage Weil <sage@redhat.com>
Thu, 7 Feb 2019 12:12:43 +0000 (06:12 -0600)
The client can speak v1 or v2, so it is misleading to identify it with a v1 or v2
address (it is either).  This avoid some kludgey workarounds.

We also are a bit more precise about what target_addr means.  It is only used by
the client to indicate which of the peer_addrs we are connecting to, or by a
peer to identify which the peer_addrs we *would* reconnect to.

Signed-off-by: Sage Weil <sage@redhat.com>
src/msg/async/AsyncConnection.cc
src/msg/async/AsyncConnection.h
src/msg/async/AsyncMessenger.cc
src/msg/async/ProtocolV2.cc

index e6727d5872bbcea6de0f79e050efca2353f37e79..d2eaa558745bb4c1f4fff36de94a357e46c4545c 100644 (file)
@@ -385,7 +385,8 @@ void AsyncConnection::process() {
     case STATE_CONNECTING_RE: {
       ssize_t r = cs.is_connected();
       if (r < 0) {
-        ldout(async_msgr->cct, 1) << __func__ << " reconnect failed " << dendl;
+        ldout(async_msgr->cct, 1) << __func__ << " reconnect failed to "
+                                 << target_addr << dendl;
         if (r == -ECONNREFUSED) {
           ldout(async_msgr->cct, 2)
               << __func__ << " connection refused!" << dendl;
@@ -478,7 +479,6 @@ void AsyncConnection::accept(ConnectedSocket socket,
   std::lock_guard<std::mutex> l(lock);
   cs = std::move(socket);
   socket_addr = listen_addr;
-  target_addr = peer_addr; // until we know better
   state = STATE_ACCEPTING;
   protocol->accept();
   // rescheduler connection in order to avoid lock dep
@@ -528,6 +528,23 @@ int AsyncConnection::send_message(Message *m)
   return 0;
 }
 
+entity_addr_t AsyncConnection::_infer_target_addr(const entity_addrvec_t& av)
+{
+  // pick the first addr of the same address family as socket_addr.  it could be
+  // an any: or v2: addr, we don't care.  it should not be a v1 addr.
+  for (auto& i : av.v) {
+    if (i.is_legacy()) {
+      continue;
+    }
+    if (i.get_family() == socket_addr.get_family()) {
+      ldout(async_msgr->cct,10) << __func__ << " " << av << " -> " << i << dendl;
+      return i;
+    }
+  }
+  ldout(async_msgr->cct,10) << __func__ << " " << av << " -> nothing to match "
+                           << socket_addr << dendl;
+  return {};
+}
 
 void AsyncConnection::fault()
 {
index c30b6d443289622c2baaede33b397247a589739d..3edd30cf96fc0a870d0eb71f9962fa1086088e11 100644 (file)
@@ -194,7 +194,9 @@ class AsyncConnection : public Connection {
   // Accepting state
   bool msgr2 = false;
   entity_addr_t socket_addr;  ///< local socket addr
-  entity_addr_t target_addr;  ///< which of the peer_addrs we're using
+  entity_addr_t target_addr;  ///< which of the peer_addrs we're connecting to (as clienet) or should reconnect to (as peer)
+
+  entity_addr_t _infer_target_addr(const entity_addrvec_t& av);
 
   // used only by "read_until"
   uint64_t state_offset;
index dba88e886f1b473d62d32045d7577a282a2df4c6..3eaae73443762c27d2a7b8ad8f904f4ee88213eb 100644 (file)
@@ -889,6 +889,7 @@ bool AsyncMessenger::learned_addr(const entity_addr_t &peer_addr_for_me)
   if (need_addr) {
     if (my_addrs->empty()) {
       auto a = peer_addr_for_me;
+      a.set_type(entity_addr_t::TYPE_ANY);
       a.set_nonce(nonce);
       if (!did_bind) {
        a.set_port(0);
index 16ed5163b5a50dafbb4bb8e347a6d5a64a509cc2..49613bfbcbbcfc945c6fd9b2a3ff5679136b95e9 100644 (file)
@@ -2212,7 +2212,7 @@ CtPtr ProtocolV2::send_client_ident() {
     ldout(cct,1) << __func__ << " getsockname reveals I am " << (sockaddr*)&ss
                 << " when talking to " << connection->target_addr << dendl;
     entity_addr_t a;
-    a.set_type(connection->target_addr.get_type());
+    a.set_type(entity_addr_t::TYPE_MSGR2); // anything but NONE; learned_addr ignores this
     a.set_sockaddr((sockaddr*)&ss);
     a.set_port(0);
     connection->lock.unlock();
@@ -2572,22 +2572,8 @@ CtPtr ProtocolV2::handle_client_ident(char *payload, uint32_t length) {
   if (client_ident.addrs().empty()) {
     return _fault();  // a v2 peer should never do this
   }
-  entity_addr_t peer_addr = client_ident.addrs().msgr2_addr();
-  if (peer_addr.type == entity_addr_t::TYPE_NONE) {
-    // no v2 addr!  they must be a client
-    if (client_ident.addrs().v.size() > 1) {
-      lderr(cct) << __func__ << " rejecting addrvec with >1 addr but no msgr2: " << client_ident.addrs() << dendl;
-      return _fault();
-    }
-    peer_addr = client_ident.addrs().legacy_addr();
-    peer_addr.set_type(entity_addr_t::TYPE_MSGR2);
-    entity_addrvec_t addrs;
-    addrs.v.push_back(peer_addr);
-    connection->set_peer_addrs(addrs);
-  } else {
-    connection->set_peer_addrs(client_ident.addrs());
-  }
-  connection->target_addr = peer_addr;
+  connection->set_peer_addrs(client_ident.addrs());
+  connection->target_addr = connection->_infer_target_addr(client_ident.addrs());
 
   peer_name = entity_name_t(connection->get_peer_type(), client_ident.gid());
 
@@ -2644,14 +2630,10 @@ CtPtr ProtocolV2::handle_reconnect(char *payload, uint32_t length) {
                 << " cs=" << reconnect.connect_seq()
                 << " ms=" << reconnect.msg_seq() << dendl;
 
-  if (reconnect.addrs().empty()) {
-    connection->set_peer_addr(connection->target_addr);
-  } else {
-    // Should we check if one of the ident.addrs match connection->target_addr
-    // as we do in ProtocolV1?
-    connection->set_peer_addrs(reconnect.addrs());
-    connection->target_addr = reconnect.addrs().msgr2_addr();
-  }
+  // Should we check if one of the ident.addrs match connection->target_addr
+  // as we do in ProtocolV1?
+  connection->set_peer_addrs(reconnect.addrs());
+  connection->target_addr = connection->_infer_target_addr(reconnect.addrs());
 
   connection->lock.unlock();
   AsyncConnectionRef existing = messenger->lookup_conn(*connection->peer_addrs);
@@ -2991,7 +2973,7 @@ CtPtr ProtocolV2::send_server_ident() {
 
   ldout(cct, 5) << __func__ << " sending identification:"
                 << " addrs=" << messenger->get_myaddrs()
-                << " peer_addr=" << connection->target_addr
+                << " target_addr=" << connection->target_addr
                 << " gid=" << messenger->get_myname().num()
                 << " global_seq=" << gs << " features_supported=" << std::hex
                 << connection->policy.features_supported