-
Notifications
You must be signed in to change notification settings - Fork 38.7k
Use Sock in CNode #23604
New issue
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
Use Sock in CNode #23604
Changes from all commits
c5dd72e
c41a116
b683491
ef5014d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -505,7 +505,16 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo | |
| if (!addr_bind.IsValid()) { | ||
| addr_bind = GetBindAddress(sock->Get()); | ||
| } | ||
| CNode* pnode = new CNode(id, nLocalServices, sock->Release(), addrConnect, CalculateKeyedNetGroup(addrConnect), nonce, addr_bind, pszDest ? pszDest : "", conn_type, /* inbound_onion */ false); | ||
| CNode* pnode = new CNode(id, | ||
| nLocalServices, | ||
| std::move(sock), | ||
| addrConnect, | ||
| CalculateKeyedNetGroup(addrConnect), | ||
| nonce, | ||
| addr_bind, | ||
| pszDest ? pszDest : "", | ||
| conn_type, | ||
| /*inbound_onion=*/false); | ||
| pnode->AddRef(); | ||
|
|
||
| // We're making a new connection, harvest entropy from the time (and our peer count) | ||
|
|
@@ -517,11 +526,10 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo | |
| void CNode::CloseSocketDisconnect() | ||
| { | ||
| fDisconnect = true; | ||
| LOCK(cs_hSocket); | ||
| if (hSocket != INVALID_SOCKET) | ||
| { | ||
| LOCK(m_sock_mutex); | ||
| if (m_sock) { | ||
| LogPrint(BCLog::NET, "disconnecting peer=%d\n", id); | ||
| CloseSocket(hSocket); | ||
| m_sock.reset(); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -799,10 +807,11 @@ size_t CConnman::SocketSendData(CNode& node) const | |
| assert(data.size() > node.nSendOffset); | ||
| int nBytes = 0; | ||
| { | ||
| LOCK(node.cs_hSocket); | ||
| if (node.hSocket == INVALID_SOCKET) | ||
| LOCK(node.m_sock_mutex); | ||
| if (!node.m_sock) { | ||
| break; | ||
| nBytes = send(node.hSocket, reinterpret_cast<const char*>(data.data()) + node.nSendOffset, data.size() - node.nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT); | ||
| } | ||
| nBytes = node.m_sock->Send(reinterpret_cast<const char*>(data.data()) + node.nSendOffset, data.size() - node.nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT); | ||
| } | ||
| if (nBytes > 0) { | ||
| node.m_last_send = GetTime<std::chrono::seconds>(); | ||
|
|
@@ -1197,7 +1206,16 @@ void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr<Sock>&& sock, | |
| } | ||
|
|
||
| const bool inbound_onion = std::find(m_onion_binds.begin(), m_onion_binds.end(), addr_bind) != m_onion_binds.end(); | ||
| CNode* pnode = new CNode(id, nodeServices, sock->Release(), addr, CalculateKeyedNetGroup(addr), nonce, addr_bind, "", ConnectionType::INBOUND, inbound_onion); | ||
| CNode* pnode = new CNode(id, | ||
| nodeServices, | ||
| std::move(sock), | ||
| addr, | ||
| CalculateKeyedNetGroup(addr), | ||
| nonce, | ||
| addr_bind, | ||
| /*addrNameIn=*/"", | ||
| ConnectionType::INBOUND, | ||
| inbound_onion); | ||
| pnode->AddRef(); | ||
| pnode->m_permissionFlags = permissionFlags; | ||
| pnode->m_prefer_evict = discouraged; | ||
|
|
@@ -1381,17 +1399,18 @@ bool CConnman::GenerateSelectSet(const std::vector<CNode*>& nodes, | |
| select_send = !pnode->vSendMsg.empty(); | ||
| } | ||
|
|
||
| LOCK(pnode->cs_hSocket); | ||
| if (pnode->hSocket == INVALID_SOCKET) | ||
| LOCK(pnode->m_sock_mutex); | ||
| if (!pnode->m_sock) { | ||
| continue; | ||
| } | ||
|
|
||
| error_set.insert(pnode->hSocket); | ||
| error_set.insert(pnode->m_sock->Get()); | ||
| if (select_send) { | ||
| send_set.insert(pnode->hSocket); | ||
| send_set.insert(pnode->m_sock->Get()); | ||
| continue; | ||
| } | ||
| if (select_recv) { | ||
| recv_set.insert(pnode->hSocket); | ||
| recv_set.insert(pnode->m_sock->Get()); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -1561,23 +1580,25 @@ void CConnman::SocketHandlerConnected(const std::vector<CNode*>& nodes, | |
| bool sendSet = false; | ||
| bool errorSet = false; | ||
| { | ||
| LOCK(pnode->cs_hSocket); | ||
| if (pnode->hSocket == INVALID_SOCKET) | ||
| LOCK(pnode->m_sock_mutex); | ||
| if (!pnode->m_sock) { | ||
| continue; | ||
| recvSet = recv_set.count(pnode->hSocket) > 0; | ||
| sendSet = send_set.count(pnode->hSocket) > 0; | ||
| errorSet = error_set.count(pnode->hSocket) > 0; | ||
| } | ||
| recvSet = recv_set.count(pnode->m_sock->Get()) > 0; | ||
| sendSet = send_set.count(pnode->m_sock->Get()) > 0; | ||
| errorSet = error_set.count(pnode->m_sock->Get()) > 0; | ||
| } | ||
| if (recvSet || errorSet) | ||
| { | ||
| // typical socket buffer is 8K-64K | ||
| uint8_t pchBuf[0x10000]; | ||
| int nBytes = 0; | ||
| { | ||
| LOCK(pnode->cs_hSocket); | ||
| if (pnode->hSocket == INVALID_SOCKET) | ||
| LOCK(pnode->m_sock_mutex); | ||
| if (!pnode->m_sock) { | ||
| continue; | ||
| nBytes = recv(pnode->hSocket, (char*)pchBuf, sizeof(pchBuf), MSG_DONTWAIT); | ||
| } | ||
| nBytes = pnode->m_sock->Recv(pchBuf, sizeof(pchBuf), MSG_DONTWAIT); | ||
| } | ||
| if (nBytes > 0) | ||
| { | ||
|
|
@@ -2962,8 +2983,9 @@ ServiceFlags CConnman::GetLocalServices() const | |
|
|
||
| unsigned int CConnman::GetReceiveFloodSize() const { return nReceiveFloodSize; } | ||
|
|
||
| CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, SOCKET hSocketIn, const CAddress& addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress& addrBindIn, const std::string& addrNameIn, ConnectionType conn_type_in, bool inbound_onion) | ||
| : m_connected{GetTime<std::chrono::seconds>()}, | ||
| CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, std::shared_ptr<Sock> sock, const CAddress& addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress& addrBindIn, const std::string& addrNameIn, ConnectionType conn_type_in, bool inbound_onion) | ||
| : m_sock{sock}, | ||
| m_connected{GetTime<std::chrono::seconds>()}, | ||
| addr(addrIn), | ||
| addrBind(addrBindIn), | ||
| m_addr_name{addrNameIn.empty() ? addr.ToStringIPPort() : addrNameIn}, | ||
|
|
@@ -2975,7 +2997,6 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, SOCKET hSocketIn, const | |
| nLocalServices(nLocalServicesIn) | ||
| { | ||
| if (inbound_onion) assert(conn_type_in == ConnectionType::INBOUND); | ||
| hSocket = hSocketIn; | ||
| if (conn_type_in != ConnectionType::BLOCK_RELAY) { | ||
| m_tx_relay = std::make_unique<TxRelay>(); | ||
| } | ||
|
|
@@ -2994,11 +3015,6 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, SOCKET hSocketIn, const | |
| m_serializer = std::make_unique<V1TransportSerializer>(V1TransportSerializer()); | ||
| } | ||
|
|
||
| CNode::~CNode() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Apologies if this is a silly question but just wanted to clarify - removing this destructor, it's implicit that the shared_ptr for Sock will be reset and the Sock's destructor will responsible for closing the socket?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See https://en.cppreference.com/w/cpp/language/destructor "Implicitly-declared destructor". The default destructor for CNode will call all the destructors of all of it's members. The destructor for shared_ptr will reduce the reference counter, and then if that reference counter is zero, the destructor for Sock will be called. If the RC is not zero, then the Sock will continue to exist on the heap (presumably being used by another thread), until the owner of that shared_ptr calls the destructor. |
||
| { | ||
| CloseSocket(hSocket); | ||
| } | ||
|
|
||
| bool CConnman::NodeFullyConnected(const CNode* pnode) | ||
| { | ||
| return pnode && pnode->fSuccessfullyConnected && !pnode->fDisconnect; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably a silly question:
LOCK(node.m_sock_mutex);applies even tonode.m_sock->Send(...)operation but then here one can return contained sockets out of the function.I understand that
m_sock_mutexguards onlym_sockmember read & write operations but not necessarily the contained socket. Is that correct or not?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is a good question.
Before this PR the mutex protects the value of the socket variable - that is, to make sure it does not change from e.g.
7(it is a file descriptor) toINVALID_SOCKETin the middle of constructs like:After this PR, it is the same with the exception that the variable is not a bare integer anymore, but a
shared_ptrand an empty such pointer is used to designate what was designated before byINVALID_SOCKET.