]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
msg/async: track target_addr for each connection
authorSage Weil <sage@redhat.com>
Tue, 12 Jun 2018 19:35:18 +0000 (14:35 -0500)
committerSage Weil <sage@redhat.com>
Tue, 3 Jul 2018 18:01:24 +0000 (13:01 -0500)
The target_addr is item from peer_addrs that we are using for the
connection.  On accept, we learn it during the handshake.  On connect,
we choose it early on (first item in addrvec that we understand).

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

index e2982b41db6b603ec1286de020946c46830a3e02..bd788d13bc126082fee11eb29d98ff8684755c3f 100644 (file)
@@ -34,7 +34,7 @@
 #define dout_prefix _conn_prefix(_dout)
 ostream& AsyncConnection::_conn_prefix(std::ostream *_dout) {
   return *_dout << "-- " << async_msgr->get_myaddrs() << " >> "
-               << peer_addrs << " conn(" << this
+               << target_addr << " conn(" << this
                << (msgr2 ? " msgr2" : " legacy")
                 << " :" << port
                 << " s=" << get_state_name(state)
@@ -1272,6 +1272,7 @@ ssize_t AsyncConnection::_process_connection()
                              << " (socket is " << socket_addr << ")" << dendl;
         }
         set_peer_addr(peer_addr);  // so that connection_state gets set up
+       target_addr = peer_addr;
         state = STATE_ACCEPTING_WAIT_CONNECT_MSG;
         break;
       }
@@ -1884,6 +1885,7 @@ void AsyncConnection::accept(ConnectedSocket socket, entity_addr_t &addr)
   std::lock_guard<std::mutex> l(lock);
   cs = std::move(socket);
   socket_addr = addr;
+  target_addr = addr; // until we know better
   state = STATE_ACCEPTING;
   // rescheduler connection in order to avoid lock dep
   center->dispatch_event_external(read_handler);
index d929805ce5f1e001f63ebfeec6113cdc35f85a3c..061b41ca6352bfbc7d700b86ca0a5345249525e1 100644 (file)
@@ -195,10 +195,11 @@ class AsyncConnection : public Connection {
   }
 
   // Only call when AsyncConnection first construct
-  void connect(const entity_addrvec_t& addrs, int type) {
+  void connect(const entity_addrvec_t& addrs, int type, entity_addr_t& target) {
     set_peer_type(type);
     set_peer_addrs(addrs);
     policy = msgr->get_policy(type);
+    target_addr = target;
     _connect();
   }
   // Only call when AsyncConnection first construct
@@ -353,6 +354,7 @@ class AsyncConnection : public Connection {
   // Accepting state
   bool msgr2 = false;
   entity_addr_t socket_addr;
+  entity_addr_t target_addr;  // which of the peer_addrs we're using
   CryptoKey session_key;
   bool replacing;    // when replacing process happened, we will reply connect
                      // side with RETRY tag and accept side will clear replaced
index d255f198dd1553329df286ae2103d2a4d5c3503c..f69579cada04ac0e0c0e875120a3516bcdcd04e6 100644 (file)
@@ -553,11 +553,23 @@ AsyncConnectionRef AsyncMessenger::create_connect(
   ldout(cct, 10) << __func__ << " " << addrs
       << ", creating connection and registering" << dendl;
 
+  // here is where we decide which of the addrs to connect to.  always prefer
+  // the first one, if we support it.
+  entity_addr_t target;
+  for (auto& a : addrs.v) {
+    if (!a.is_msgr2() && !a.is_legacy()) {
+      continue;
+    }
+    // FIXME: for ipv4 vs ipv6, check whether local host can handle ipv6 before
+    // trying it?  for now, just pick whichever is listed first.
+    target = a;
+  }
+
   // create connection
   Worker *w = stack->get_worker();
   AsyncConnectionRef conn = new AsyncConnection(cct, this, &dispatch_queue, w,
-                                               addrs.front().is_msgr2());
-  conn->connect(addrs, type);
+                                               target.is_msgr2());
+  conn->connect(addrs, type, target);
   assert(!conns.count(addrs));
   conns[addrs] = conn;
   w->get_perf_counter()->inc(l_msgr_active_connections);