We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
libp2p目录中Service.cpp代码逻辑有问题,在特殊情况下会出现一对节点互相无法联通的。
经过排查,发现是在Disconnect duplicate peer时,并没有真正关闭连接,使得一对节点互相持有对方早已移除的连接,从而无法完成通信。
在Service::onConnect中,如果出现duplicate peer,会执行session->disconnect(rock::network::DuplicatePeer)
Service::onConnect
session->disconnect(rock::network::DuplicatePeer)
onConnect函数关键代码如下:
auto it = m_sessions.find(nodeID); if (it != m_sessions.end() && it->second->actived()) { SERVICE_LOG(TRACE) << "Disconnect duplicate peer" << LOG_KV("nodeID", nodeID.abridged()); updateStaticNodes(session->socket(), nodeID); session->disconnect(rock::network::DuplicatePeer); return; }
session的disconnect函数会调用drop函数:
void Session::disconnect(DisconnectReason _reason) { drop(_reason); }
在drop函数中,我们发现"drop, call and erase all callbackFunc in this session!"这个日志从未出现过,经分析,是此时m_actived是false,使得drop函数提前退出了,并没有真正去close掉duplicate的peer。
m_actived
void Session::drop(DisconnectReason _reason) { auto server = m_server.lock(); if (!m_actived) return; if (m_readIdleTimer) { m_readIdleTimer->cancel(); } if (m_writeIdleTimer) { m_writeIdleTimer->cancel(); } m_actived = false; int errorCode = P2PExceptionType::Disconnect; std::string errorMsg = "Disconnect"; if (_reason == DuplicatePeer) { errorCode = P2PExceptionType::DuplicateSession; errorMsg = "DuplicateSession"; } SESSION_LOG(INFO) << "drop, call and erase all callbackFunc in this session!" << LOG_KV("endpoint", nodeIPEndpoint()); rock::common::core::RecursiveGuard l(x_seq2Callback);
The text was updated successfully, but these errors were encountered:
我检查了代码,你描述的disconnect没有关闭当前的socket是可能的,但逻辑上这个问题不会影响两个节点的链接,因为这个session会被丢弃,当其析构时会关闭socket。 另外这里的逻辑说明新链接是重复的,也就是节点间已经存在一个链接,所以两个节点连接不上是不是找错了原因?
Sorry, something went wrong.
的逻辑说明新链接是重复的,也就是节点间已经存在一个链接,所以两个节点连接不上是不是找错了原因?
嗯嗯感谢回复,我之后check了一下,这确实不是主要原因,我观察到日志中两个节点在频繁建立链接,所以推测发生两个节点连接不上的可能原因是:
两个链接1和2,A节点认为1先于2建立,所以断了2,而B节点认为2先于1建立,所以断了1,然后都连不上,再尝试链接,循环往复。
具体的例子可能如下:
A收到链接1的第二次握手,认为链接1建立成功,调用onConnect,将链接1添加到session中。 A给B发送链接1的第三次握手 B在收到链接1的第三次握手前,已经收到链接2的第二次握手,调用onConnect,将链接2添加到session中。 B给A发送链接2的第三次握手 B收到链接1的第三次握手,发现session中已经有链接2了,所以断掉链接1 A收到链接2的第三次握手,发现session中已经有链接1了,所以断掉链接2
之后双方发现session均已关闭,又发起互相的链接请求,循环上述过程。
@Tianpingan 听起来是有可能发生的,但这个发生的概率应该很低,节点每10s尝试去链接其他节点,除非每次都发生互相连接而处理顺序不同导致断开,否则最终应该还是能建立链接。能否请您提供发生问题时两个节点的日志,我们根据日志来跟进排查这个问题
bxq2011hust
No branches or pull requests
libp2p目录中Service.cpp代码逻辑有问题,在特殊情况下会出现一对节点互相无法联通的。
经过排查,发现是在Disconnect duplicate peer时,并没有真正关闭连接,使得一对节点互相持有对方早已移除的连接,从而无法完成通信。
在
Service::onConnect
中,如果出现duplicate peer,会执行session->disconnect(rock::network::DuplicatePeer)
onConnect函数关键代码如下:
session的disconnect函数会调用drop函数:
在drop函数中,我们发现"drop, call and erase all callbackFunc in this session!"这个日志从未出现过,经分析,是此时
m_actived
是false,使得drop函数提前退出了,并没有真正去close掉duplicate的peer。The text was updated successfully, but these errors were encountered: