From db320dd096a1d15d47e14f4c8021d3f0074b0690 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 28 Jan 2019 02:15:23 -0600 Subject: [PATCH] msg/async: identify client using any: addr 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 --- src/msg/async/AsyncConnection.cc | 21 ++++++++++++++++++-- src/msg/async/AsyncConnection.h | 4 +++- src/msg/async/AsyncMessenger.cc | 1 + src/msg/async/ProtocolV2.cc | 34 ++++++++------------------------ 4 files changed, 31 insertions(+), 29 deletions(-) diff --git a/src/msg/async/AsyncConnection.cc b/src/msg/async/AsyncConnection.cc index e6727d5872b..d2eaa558745 100644 --- a/src/msg/async/AsyncConnection.cc +++ b/src/msg/async/AsyncConnection.cc @@ -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 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() { diff --git a/src/msg/async/AsyncConnection.h b/src/msg/async/AsyncConnection.h index c30b6d44328..3edd30cf96f 100644 --- a/src/msg/async/AsyncConnection.h +++ b/src/msg/async/AsyncConnection.h @@ -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; diff --git a/src/msg/async/AsyncMessenger.cc b/src/msg/async/AsyncMessenger.cc index dba88e886f1..3eaae734437 100644 --- a/src/msg/async/AsyncMessenger.cc +++ b/src/msg/async/AsyncMessenger.cc @@ -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); diff --git a/src/msg/async/ProtocolV2.cc b/src/msg/async/ProtocolV2.cc index 16ed5163b5a..49613bfbcbb 100644 --- a/src/msg/async/ProtocolV2.cc +++ b/src/msg/async/ProtocolV2.cc @@ -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 -- 2.39.5