mirror of
https://github.com/SChernykh/p2pool.git
synced 2025-01-09 20:30:05 +00:00
P2PServer: added more protocol checks
This commit is contained in:
parent
03f829e18c
commit
752e2381d6
2 changed files with 55 additions and 6 deletions
|
@ -290,9 +290,9 @@ void P2PServer::update_peer_list()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur_time >= client->m_nextPeerListRequest) {
|
if (cur_time >= client->m_nextOutgoingPeerListRequest) {
|
||||||
// Send peer list requests at random intervals (60-120 seconds)
|
// Send peer list requests at random intervals (60-120 seconds)
|
||||||
client->m_nextPeerListRequest = cur_time + 60 + (get_random64() % 61);
|
client->m_nextOutgoingPeerListRequest = cur_time + 60 + (get_random64() % 61);
|
||||||
|
|
||||||
const bool result = send(client,
|
const bool result = send(client,
|
||||||
[](void* buf)
|
[](void* buf)
|
||||||
|
@ -945,7 +945,7 @@ void P2PServer::download_missing_blocks()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
send(client,
|
const bool result = send(client,
|
||||||
[&id](void* buf)
|
[&id](void* buf)
|
||||||
{
|
{
|
||||||
uint8_t* p0 = reinterpret_cast<uint8_t*>(buf);
|
uint8_t* p0 = reinterpret_cast<uint8_t*>(buf);
|
||||||
|
@ -959,6 +959,10 @@ void P2PServer::download_missing_blocks()
|
||||||
|
|
||||||
return p - p0;
|
return p - p0;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
++client->m_blockPendingRequests;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -985,10 +989,12 @@ P2PServer::P2PClient::P2PClient()
|
||||||
, m_handshakeComplete(false)
|
, m_handshakeComplete(false)
|
||||||
, m_handshakeInvalid(false)
|
, m_handshakeInvalid(false)
|
||||||
, m_listenPort(-1)
|
, m_listenPort(-1)
|
||||||
, m_nextPeerListRequest(0)
|
, m_prevIncomingPeerListRequest(0)
|
||||||
|
, m_nextOutgoingPeerListRequest(0)
|
||||||
, m_lastPeerListRequestTime{}
|
, m_lastPeerListRequestTime{}
|
||||||
, m_peerListPendingRequests(0)
|
, m_peerListPendingRequests(0)
|
||||||
, m_pingTime(0)
|
, m_pingTime(0)
|
||||||
|
, m_blockPendingRequests(0)
|
||||||
, m_lastAlive(0)
|
, m_lastAlive(0)
|
||||||
, m_lastBroadcastTimestamp(0)
|
, m_lastBroadcastTimestamp(0)
|
||||||
, m_lastBlockrequestTimestamp(0)
|
, m_lastBlockrequestTimestamp(0)
|
||||||
|
@ -1011,10 +1017,12 @@ void P2PServer::P2PClient::reset()
|
||||||
m_handshakeComplete = false;
|
m_handshakeComplete = false;
|
||||||
m_handshakeInvalid = false;
|
m_handshakeInvalid = false;
|
||||||
m_listenPort = -1;
|
m_listenPort = -1;
|
||||||
m_nextPeerListRequest = 0;
|
m_prevIncomingPeerListRequest = 0;
|
||||||
|
m_nextOutgoingPeerListRequest = 0;
|
||||||
m_lastPeerListRequestTime = {};
|
m_lastPeerListRequestTime = {};
|
||||||
m_peerListPendingRequests = 0;
|
m_peerListPendingRequests = 0;
|
||||||
m_pingTime = 0;
|
m_pingTime = 0;
|
||||||
|
m_blockPendingRequests = 0;
|
||||||
m_lastAlive = 0;
|
m_lastAlive = 0;
|
||||||
m_lastBroadcastTimestamp = 0;
|
m_lastBroadcastTimestamp = 0;
|
||||||
m_lastBlockrequestTimestamp = 0;
|
m_lastBlockrequestTimestamp = 0;
|
||||||
|
@ -1071,6 +1079,8 @@ bool P2PServer::P2PClient::on_read(char* data, uint32_t size)
|
||||||
uint8_t* buf = buf_begin;
|
uint8_t* buf = buf_begin;
|
||||||
uint32_t bytes_left = m_numRead;
|
uint32_t bytes_left = m_numRead;
|
||||||
|
|
||||||
|
uint32_t num_block_requests = 0;
|
||||||
|
|
||||||
uint32_t bytes_read;
|
uint32_t bytes_read;
|
||||||
do {
|
do {
|
||||||
MessageId id = static_cast<MessageId>(buf[0]);
|
MessageId id = static_cast<MessageId>(buf[0]);
|
||||||
|
@ -1128,6 +1138,13 @@ bool P2PServer::P2PClient::on_read(char* data, uint32_t size)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MessageId::LISTEN_PORT:
|
case MessageId::LISTEN_PORT:
|
||||||
|
if (m_listenPort >= 0) {
|
||||||
|
LOGWARN(4, "peer " << static_cast<char*>(m_addrString) << " sent an unexpected LISTEN_PORT");
|
||||||
|
ban(DEFAULT_BAN_TIME);
|
||||||
|
server->remove_peer_from_list(this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
LOGINFO(5, "peer " << log::Gray() << static_cast<char*>(m_addrString) << log::NoColor() << " sent LISTEN_PORT");
|
LOGINFO(5, "peer " << log::Gray() << static_cast<char*>(m_addrString) << log::NoColor() << " sent LISTEN_PORT");
|
||||||
|
|
||||||
if (bytes_left >= 1 + sizeof(int32_t)) {
|
if (bytes_left >= 1 + sizeof(int32_t)) {
|
||||||
|
@ -1141,6 +1158,14 @@ bool P2PServer::P2PClient::on_read(char* data, uint32_t size)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MessageId::BLOCK_REQUEST:
|
case MessageId::BLOCK_REQUEST:
|
||||||
|
++num_block_requests;
|
||||||
|
if (num_block_requests > 100) {
|
||||||
|
LOGWARN(4, "peer " << log::Gray() << static_cast<char*>(m_addrString) << log::NoColor() << " sent too many BLOCK_REQUEST messages at once");
|
||||||
|
ban(DEFAULT_BAN_TIME);
|
||||||
|
server->remove_peer_from_list(this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
LOGINFO(5, "peer " << log::Gray() << static_cast<char*>(m_addrString) << log::NoColor() << " sent BLOCK_REQUEST");
|
LOGINFO(5, "peer " << log::Gray() << static_cast<char*>(m_addrString) << log::NoColor() << " sent BLOCK_REQUEST");
|
||||||
|
|
||||||
if (bytes_left >= 1 + HASH_SIZE) {
|
if (bytes_left >= 1 + HASH_SIZE) {
|
||||||
|
@ -1154,12 +1179,21 @@ bool P2PServer::P2PClient::on_read(char* data, uint32_t size)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MessageId::BLOCK_RESPONSE:
|
case MessageId::BLOCK_RESPONSE:
|
||||||
|
if (m_blockPendingRequests <= 0) {
|
||||||
|
LOGWARN(4, "peer " << log::Gray() << static_cast<char*>(m_addrString) << log::NoColor() << " sent an unexpected BLOCK_RESPONSE");
|
||||||
|
ban(DEFAULT_BAN_TIME);
|
||||||
|
server->remove_peer_from_list(this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
LOGINFO(5, "peer " << log::Gray() << static_cast<char*>(m_addrString) << log::NoColor() << " sent BLOCK_RESPONSE");
|
LOGINFO(5, "peer " << log::Gray() << static_cast<char*>(m_addrString) << log::NoColor() << " sent BLOCK_RESPONSE");
|
||||||
|
|
||||||
if (bytes_left >= 1 + sizeof(uint32_t)) {
|
if (bytes_left >= 1 + sizeof(uint32_t)) {
|
||||||
const uint32_t block_size = *reinterpret_cast<uint32_t*>(buf + 1);
|
const uint32_t block_size = *reinterpret_cast<uint32_t*>(buf + 1);
|
||||||
if (bytes_left >= 1 + sizeof(uint32_t) + block_size) {
|
if (bytes_left >= 1 + sizeof(uint32_t) + block_size) {
|
||||||
bytes_read = 1 + sizeof(uint32_t) + block_size;
|
bytes_read = 1 + sizeof(uint32_t) + block_size;
|
||||||
|
|
||||||
|
--m_blockPendingRequests;
|
||||||
if (!on_block_response(buf + 1 + sizeof(uint32_t), block_size)) {
|
if (!on_block_response(buf + 1 + sizeof(uint32_t), block_size)) {
|
||||||
ban(DEFAULT_BAN_TIME);
|
ban(DEFAULT_BAN_TIME);
|
||||||
server->remove_peer_from_list(this);
|
server->remove_peer_from_list(this);
|
||||||
|
@ -1571,6 +1605,7 @@ void P2PServer::P2PClient::on_after_handshake(uint8_t* &p)
|
||||||
memcpy(p, empty.h, HASH_SIZE);
|
memcpy(p, empty.h, HASH_SIZE);
|
||||||
p += HASH_SIZE;
|
p += HASH_SIZE;
|
||||||
|
|
||||||
|
++m_blockPendingRequests;
|
||||||
m_lastBroadcastTimestamp = time(nullptr);
|
m_lastBroadcastTimestamp = time(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1706,6 +1741,15 @@ bool P2PServer::P2PClient::on_block_broadcast(const uint8_t* buf, uint32_t size)
|
||||||
bool P2PServer::P2PClient::on_peer_list_request(const uint8_t*)
|
bool P2PServer::P2PClient::on_peer_list_request(const uint8_t*)
|
||||||
{
|
{
|
||||||
P2PServer* server = static_cast<P2PServer*>(m_owner);
|
P2PServer* server = static_cast<P2PServer*>(m_owner);
|
||||||
|
const time_t cur_time = time(nullptr);
|
||||||
|
|
||||||
|
// Allow peer list requests no more than once every 30 seconds
|
||||||
|
if (cur_time < m_prevIncomingPeerListRequest + 30) {
|
||||||
|
LOGWARN(4, "peer " << log::Gray() << static_cast<char*>(m_addrString) << log::NoColor() << " is sending PEER_LIST_REQUEST too often");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_prevIncomingPeerListRequest = cur_time;
|
||||||
|
|
||||||
Peer peers[PEER_LIST_RESPONSE_MAX_PEERS];
|
Peer peers[PEER_LIST_RESPONSE_MAX_PEERS];
|
||||||
uint32_t num_selected_peers = 0;
|
uint32_t num_selected_peers = 0;
|
||||||
|
@ -1916,6 +1960,8 @@ void P2PServer::P2PClient::post_handle_incoming_block(const uint32_t reset_count
|
||||||
if (!result) {
|
if (!result) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
++m_blockPendingRequests;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -110,11 +110,14 @@ public:
|
||||||
bool m_handshakeInvalid;
|
bool m_handshakeInvalid;
|
||||||
int m_listenPort;
|
int m_listenPort;
|
||||||
|
|
||||||
time_t m_nextPeerListRequest;
|
time_t m_prevIncomingPeerListRequest;
|
||||||
|
time_t m_nextOutgoingPeerListRequest;
|
||||||
std::chrono::system_clock::time_point m_lastPeerListRequestTime;
|
std::chrono::system_clock::time_point m_lastPeerListRequestTime;
|
||||||
int m_peerListPendingRequests;
|
int m_peerListPendingRequests;
|
||||||
int64_t m_pingTime;
|
int64_t m_pingTime;
|
||||||
|
|
||||||
|
int m_blockPendingRequests;
|
||||||
|
|
||||||
time_t m_lastAlive;
|
time_t m_lastAlive;
|
||||||
time_t m_lastBroadcastTimestamp;
|
time_t m_lastBroadcastTimestamp;
|
||||||
time_t m_lastBlockrequestTimestamp;
|
time_t m_lastBlockrequestTimestamp;
|
||||||
|
|
Loading…
Reference in a new issue