mirror of
https://github.com/SChernykh/p2pool.git
synced 2024-12-23 03:49:23 +00:00
TCPServer: use /64 prefix to ban IPv6 peers
This commit is contained in:
parent
754eb78a05
commit
c94b627808
6 changed files with 31 additions and 18 deletions
|
@ -591,7 +591,7 @@ void P2PServer::load_peer_list()
|
||||||
p.m_numFailedConnections = 0;
|
p.m_numFailedConnections = 0;
|
||||||
p.m_lastSeen = seconds_since_epoch();
|
p.m_lastSeen = seconds_since_epoch();
|
||||||
|
|
||||||
if (!already_added && !is_banned(p.m_addr)) {
|
if (!already_added && !is_banned(p.m_isV6, p.m_addr)) {
|
||||||
m_peerList.push_back(p);
|
m_peerList.push_back(p);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -661,7 +661,7 @@ void P2PServer::load_monerod_peer_list()
|
||||||
p.m_port = port;
|
p.m_port = port;
|
||||||
p.m_numFailedConnections = 0;
|
p.m_numFailedConnections = 0;
|
||||||
|
|
||||||
if (!is_banned(p.m_addr)) {
|
if (!is_banned(p.m_isV6, p.m_addr)) {
|
||||||
m_peerListMonero.push_back(p);
|
m_peerListMonero.push_back(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -694,7 +694,7 @@ void P2PServer::update_peer_in_list(bool is_v6, const raw_ip& ip, int port)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_banned(ip)) {
|
if (!is_banned(is_v6, ip)) {
|
||||||
m_peerList.emplace_back(Peer{ is_v6, ip, port, 0, cur_time });
|
m_peerList.emplace_back(Peer{ is_v6, ip, port, 0, cur_time });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2237,7 +2237,7 @@ void P2PServer::P2PClient::on_peer_list_response(const uint8_t* buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!already_added && !server->is_banned(ip)) {
|
if (!already_added && !server->is_banned(is_v6, ip)) {
|
||||||
server->m_peerList.emplace_back(Peer{ is_v6, ip, port, 0, cur_time });
|
server->m_peerList.emplace_back(Peer{ is_v6, ip, port, 0, cur_time });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2306,11 +2306,12 @@ bool P2PServer::P2PClient::handle_incoming_block_async(const PoolBlock* block, u
|
||||||
P2PClient* client;
|
P2PClient* client;
|
||||||
P2PServer* server;
|
P2PServer* server;
|
||||||
uint32_t client_reset_counter;
|
uint32_t client_reset_counter;
|
||||||
|
bool client_isV6;
|
||||||
raw_ip client_ip;
|
raw_ip client_ip;
|
||||||
std::vector<hash> missing_blocks;
|
std::vector<hash> missing_blocks;
|
||||||
};
|
};
|
||||||
|
|
||||||
Work* work = new Work{ {}, *block, this, server, m_resetCounter.load(), m_addr, {} };
|
Work* work = new Work{ {}, *block, this, server, m_resetCounter.load(), m_isV6, m_addr, {} };
|
||||||
work->req.data = work;
|
work->req.data = work;
|
||||||
|
|
||||||
const int err = uv_queue_work(&server->m_loop, &work->req,
|
const int err = uv_queue_work(&server->m_loop, &work->req,
|
||||||
|
@ -2318,7 +2319,7 @@ bool P2PServer::P2PClient::handle_incoming_block_async(const PoolBlock* block, u
|
||||||
{
|
{
|
||||||
BACKGROUND_JOB_START(P2PServer::handle_incoming_block_async);
|
BACKGROUND_JOB_START(P2PServer::handle_incoming_block_async);
|
||||||
Work* work = reinterpret_cast<Work*>(req->data);
|
Work* work = reinterpret_cast<Work*>(req->data);
|
||||||
work->client->handle_incoming_block(work->server->m_pool, work->block, work->client_reset_counter, work->client_ip, work->missing_blocks);
|
work->client->handle_incoming_block(work->server->m_pool, work->block, work->client_reset_counter, work->client_isV6, work->client_ip, work->missing_blocks);
|
||||||
},
|
},
|
||||||
[](uv_work_t* req, int /*status*/)
|
[](uv_work_t* req, int /*status*/)
|
||||||
{
|
{
|
||||||
|
@ -2337,7 +2338,7 @@ bool P2PServer::P2PClient::handle_incoming_block_async(const PoolBlock* block, u
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void P2PServer::P2PClient::handle_incoming_block(p2pool* pool, PoolBlock& block, const uint32_t reset_counter, const raw_ip& addr, std::vector<hash>& missing_blocks)
|
void P2PServer::P2PClient::handle_incoming_block(p2pool* pool, PoolBlock& block, const uint32_t reset_counter, bool is_v6, const raw_ip& addr, std::vector<hash>& missing_blocks)
|
||||||
{
|
{
|
||||||
if (!pool->side_chain().add_external_block(block, missing_blocks)) {
|
if (!pool->side_chain().add_external_block(block, missing_blocks)) {
|
||||||
// Client sent bad data, disconnect and ban it
|
// Client sent bad data, disconnect and ban it
|
||||||
|
@ -2351,7 +2352,7 @@ void P2PServer::P2PClient::handle_incoming_block(p2pool* pool, PoolBlock& block,
|
||||||
}
|
}
|
||||||
|
|
||||||
P2PServer* server = pool->p2p_server();
|
P2PServer* server = pool->p2p_server();
|
||||||
server->ban(addr, DEFAULT_BAN_TIME);
|
server->ban(is_v6, addr, DEFAULT_BAN_TIME);
|
||||||
server->remove_peer_from_list(addr);
|
server->remove_peer_from_list(addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ public:
|
||||||
void on_peer_list_response(const uint8_t* buf);
|
void on_peer_list_response(const uint8_t* buf);
|
||||||
|
|
||||||
bool handle_incoming_block_async(const PoolBlock* block, uint64_t max_time_delta = 0);
|
bool handle_incoming_block_async(const PoolBlock* block, uint64_t max_time_delta = 0);
|
||||||
void handle_incoming_block(p2pool* pool, PoolBlock& block, const uint32_t reset_counter, const raw_ip& addr, std::vector<hash>& missing_blocks);
|
void handle_incoming_block(p2pool* pool, PoolBlock& block, const uint32_t reset_counter, bool is_v6, const raw_ip& addr, std::vector<hash>& missing_blocks);
|
||||||
void post_handle_incoming_block(const uint32_t reset_counter, std::vector<hash>& missing_blocks);
|
void post_handle_incoming_block(const uint32_t reset_counter, std::vector<hash>& missing_blocks);
|
||||||
|
|
||||||
bool is_good() const { return m_handshakeComplete && !m_handshakeInvalid && (m_listenPort >= 0); }
|
bool is_good() const { return m_handshakeComplete && !m_handshakeInvalid && (m_listenPort >= 0); }
|
||||||
|
|
|
@ -410,6 +410,7 @@ bool StratumServer::on_submit(StratumClient* client, uint32_t id, const char* jo
|
||||||
share->m_req.data = share;
|
share->m_req.data = share;
|
||||||
share->m_server = this;
|
share->m_server = this;
|
||||||
share->m_client = client;
|
share->m_client = client;
|
||||||
|
share->m_clientIPv6 = client->m_isV6;
|
||||||
share->m_clientAddr = client->m_addr;
|
share->m_clientAddr = client->m_addr;
|
||||||
share->m_clientResetCounter = client->m_resetCounter.load();
|
share->m_clientResetCounter = client->m_resetCounter.load();
|
||||||
share->m_rpcId = client->m_rpcId;
|
share->m_rpcId = client->m_rpcId;
|
||||||
|
@ -843,7 +844,7 @@ void StratumServer::on_share_found(uv_work_t* req)
|
||||||
SubmittedShare* share = reinterpret_cast<SubmittedShare*>(req->data);
|
SubmittedShare* share = reinterpret_cast<SubmittedShare*>(req->data);
|
||||||
StratumServer* server = share->m_server;
|
StratumServer* server = share->m_server;
|
||||||
|
|
||||||
if (server->is_banned(share->m_clientAddr)) {
|
if (server->is_banned(share->m_clientIPv6, share->m_clientAddr)) {
|
||||||
share->m_highEnoughDifficulty = false;
|
share->m_highEnoughDifficulty = false;
|
||||||
share->m_result = SubmittedShare::Result::BANNED;
|
share->m_result = SubmittedShare::Result::BANNED;
|
||||||
return;
|
return;
|
||||||
|
@ -1019,7 +1020,7 @@ void StratumServer::on_after_share_found(uv_work_t* req, int /*status*/)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (bad_share) {
|
else if (bad_share) {
|
||||||
server->ban(share->m_clientAddr, DEFAULT_BAN_TIME);
|
server->ban(share->m_clientIPv6, share->m_clientAddr, DEFAULT_BAN_TIME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -142,6 +142,7 @@ private:
|
||||||
uv_work_t m_req;
|
uv_work_t m_req;
|
||||||
StratumServer* m_server;
|
StratumServer* m_server;
|
||||||
StratumClient* m_client;
|
StratumClient* m_client;
|
||||||
|
bool m_clientIPv6;
|
||||||
raw_ip m_clientAddr;
|
raw_ip m_clientAddr;
|
||||||
uint32_t m_clientResetCounter;
|
uint32_t m_clientResetCounter;
|
||||||
uint32_t m_rpcId;
|
uint32_t m_rpcId;
|
||||||
|
|
|
@ -300,12 +300,17 @@ bool TCPServer::connect_to_peer(bool is_v6, const raw_ip& ip, int port)
|
||||||
return connect_to_peer(client);
|
return connect_to_peer(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TCPServer::is_banned(const raw_ip& ip)
|
bool TCPServer::is_banned(bool is_v6, raw_ip ip)
|
||||||
{
|
{
|
||||||
if (ip.is_localhost()) {
|
if (ip.is_localhost()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If it's IPv6, check the whole /64 prefix
|
||||||
|
if (is_v6 && !ip.is_ipv4_prefix()) {
|
||||||
|
memset(ip.data + 8, 0, sizeof(ip.data) - 8);
|
||||||
|
}
|
||||||
|
|
||||||
const auto cur_time = std::chrono::steady_clock::now();
|
const auto cur_time = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
MutexLock lock(m_bansLock);
|
MutexLock lock(m_bansLock);
|
||||||
|
@ -324,7 +329,7 @@ bool TCPServer::is_banned(const raw_ip& ip)
|
||||||
|
|
||||||
bool TCPServer::connect_to_peer(Client* client)
|
bool TCPServer::connect_to_peer(Client* client)
|
||||||
{
|
{
|
||||||
if (is_banned(client->m_addr)) {
|
if (is_banned(client->m_isV6, client->m_addr)) {
|
||||||
LOGINFO(5, "peer " << log::Gray() << static_cast<char*>(client->m_addrString) << log::NoColor() << " is banned, not connecting to it");
|
LOGINFO(5, "peer " << log::Gray() << static_cast<char*>(client->m_addrString) << log::NoColor() << " is banned, not connecting to it");
|
||||||
return_client(client);
|
return_client(client);
|
||||||
return false;
|
return false;
|
||||||
|
@ -482,12 +487,17 @@ void TCPServer::print_status()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TCPServer::ban(const raw_ip& ip, uint64_t seconds)
|
void TCPServer::ban(bool is_v6, raw_ip ip, uint64_t seconds)
|
||||||
{
|
{
|
||||||
if (ip.is_localhost()) {
|
if (ip.is_localhost()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If it's IPv6, ban the whole /64 prefix
|
||||||
|
if (is_v6 && !ip.is_ipv4_prefix()) {
|
||||||
|
memset(ip.data + 8, 0, sizeof(ip.data) - 8);
|
||||||
|
}
|
||||||
|
|
||||||
const auto ban_time = std::chrono::steady_clock::now() + std::chrono::seconds(seconds);
|
const auto ban_time = std::chrono::steady_clock::now() + std::chrono::seconds(seconds);
|
||||||
|
|
||||||
MutexLock lock(m_bansLock);
|
MutexLock lock(m_bansLock);
|
||||||
|
@ -772,7 +782,7 @@ void TCPServer::on_new_client(uv_stream_t* server, Client* client)
|
||||||
|
|
||||||
LOGINFO(5, "new connection " << (client->m_isIncoming ? "from " : "to ") << log::Gray() << static_cast<char*>(client->m_addrString));
|
LOGINFO(5, "new connection " << (client->m_isIncoming ? "from " : "to ") << log::Gray() << static_cast<char*>(client->m_addrString));
|
||||||
|
|
||||||
if (is_banned(client->m_addr)) {
|
if (is_banned(client->m_isV6, client->m_addr)) {
|
||||||
LOGINFO(5, "peer " << log::Gray() << static_cast<char*>(client->m_addrString) << log::NoColor() << " is banned, disconnecting");
|
LOGINFO(5, "peer " << log::Gray() << static_cast<char*>(client->m_addrString) << log::NoColor() << " is banned, disconnecting");
|
||||||
client->close();
|
client->close();
|
||||||
return;
|
return;
|
||||||
|
@ -1209,7 +1219,7 @@ void TCPServer::Client::ban(uint64_t seconds)
|
||||||
|
|
||||||
if (m_owner) {
|
if (m_owner) {
|
||||||
LOGWARN(3, "peer " << static_cast<char*>(m_addrString) << " banned for " << seconds << " seconds");
|
LOGWARN(3, "peer " << static_cast<char*>(m_addrString) << " banned for " << seconds << " seconds");
|
||||||
m_owner->ban(m_addr, seconds);
|
m_owner->ban(m_isV6, m_addr, seconds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ public:
|
||||||
bool connect_to_peer(bool is_v6, const raw_ip& ip, int port);
|
bool connect_to_peer(bool is_v6, const raw_ip& ip, int port);
|
||||||
virtual void on_connect_failed(bool /*is_v6*/, const raw_ip& /*ip*/, int /*port*/) {}
|
virtual void on_connect_failed(bool /*is_v6*/, const raw_ip& /*ip*/, int /*port*/) {}
|
||||||
|
|
||||||
void ban(const raw_ip& ip, uint64_t seconds);
|
void ban(bool is_v6, raw_ip ip, uint64_t seconds);
|
||||||
virtual void print_bans();
|
virtual void print_bans();
|
||||||
|
|
||||||
struct Client
|
struct Client
|
||||||
|
@ -188,7 +188,7 @@ protected:
|
||||||
uv_mutex_t m_bansLock;
|
uv_mutex_t m_bansLock;
|
||||||
unordered_map<raw_ip, std::chrono::steady_clock::time_point> m_bans;
|
unordered_map<raw_ip, std::chrono::steady_clock::time_point> m_bans;
|
||||||
|
|
||||||
bool is_banned(const raw_ip& ip);
|
bool is_banned(bool is_v6, raw_ip ip);
|
||||||
|
|
||||||
unordered_set<raw_ip> m_pendingConnections;
|
unordered_set<raw_ip> m_pendingConnections;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue