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;
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
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()
{
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();
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());
<< " 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);
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