mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
Ratelimit nochannel ADNL packets (#1147)
* Get ADNL stats in validator console * Add timestamp to stats * Limit nochannel adnl packets --------- Co-authored-by: SpyCheese <mikle98@yandex.ru>
This commit is contained in:
parent
e08111159f
commit
b2b79fead1
18 changed files with 838 additions and 175 deletions
|
@ -41,20 +41,34 @@ AdnlAddressList AdnlLocalId::get_addr_list() const {
|
|||
}
|
||||
|
||||
void AdnlLocalId::receive(td::IPAddress addr, td::BufferSlice data) {
|
||||
auto P = td::PromiseCreator::lambda(
|
||||
[peer_table = peer_table_, dst = short_id_, addr, id = print_id()](td::Result<AdnlPacket> R) {
|
||||
if (R.is_error()) {
|
||||
VLOG(ADNL_WARNING) << id << ": dropping IN message: cannot decrypt: " << R.move_as_error();
|
||||
} else {
|
||||
auto packet = R.move_as_ok();
|
||||
packet.set_remote_addr(addr);
|
||||
td::actor::send_closure(peer_table, &AdnlPeerTable::receive_decrypted_packet, dst, std::move(packet));
|
||||
}
|
||||
});
|
||||
|
||||
InboundRateLimiter& rate_limiter = inbound_rate_limiter_[addr];
|
||||
if (!rate_limiter.rate_limiter.take()) {
|
||||
VLOG(ADNL_NOTICE) << this << ": dropping IN message: rate limit exceeded";
|
||||
add_dropped_packet_stats(addr);
|
||||
return;
|
||||
}
|
||||
++rate_limiter.currently_decrypting_packets;
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), peer_table = peer_table_, dst = short_id_, addr,
|
||||
id = print_id(), size = data.size()](td::Result<AdnlPacket> R) {
|
||||
td::actor::send_closure(SelfId, &AdnlLocalId::decrypt_packet_done, addr);
|
||||
if (R.is_error()) {
|
||||
VLOG(ADNL_WARNING) << id << ": dropping IN message: cannot decrypt: " << R.move_as_error();
|
||||
} else {
|
||||
auto packet = R.move_as_ok();
|
||||
packet.set_remote_addr(addr);
|
||||
td::actor::send_closure(peer_table, &AdnlPeerTable::receive_decrypted_packet, dst, std::move(packet), size);
|
||||
}
|
||||
});
|
||||
decrypt(std::move(data), std::move(P));
|
||||
}
|
||||
|
||||
void AdnlLocalId::decrypt_packet_done(td::IPAddress addr) {
|
||||
auto it = inbound_rate_limiter_.find(addr);
|
||||
CHECK(it != inbound_rate_limiter_.end());
|
||||
--it->second.currently_decrypting_packets;
|
||||
add_decrypted_packet_stats(addr);
|
||||
}
|
||||
|
||||
void AdnlLocalId::deliver(AdnlNodeIdShort src, td::BufferSlice data) {
|
||||
auto s = std::move(data);
|
||||
for (auto &cb : cb_) {
|
||||
|
@ -292,6 +306,67 @@ void AdnlLocalId::update_packet(AdnlPacket packet, bool update_id, bool sign, td
|
|||
}
|
||||
}
|
||||
|
||||
void AdnlLocalId::get_stats(td::Promise<tl_object_ptr<ton_api::adnl_stats_localId>> promise) {
|
||||
auto stats = create_tl_object<ton_api::adnl_stats_localId>();
|
||||
stats->short_id_ = short_id_.bits256_value();
|
||||
for (auto &[ip, x] : inbound_rate_limiter_) {
|
||||
if (x.currently_decrypting_packets != 0) {
|
||||
stats->current_decrypt_.push_back(create_tl_object<ton_api::adnl_stats_ipPackets>(
|
||||
ip.is_valid() ? PSTRING() << ip.get_ip_str() << ":" << ip.get_port() : "", x.currently_decrypting_packets));
|
||||
}
|
||||
}
|
||||
prepare_packet_stats();
|
||||
stats->packets_recent_ = packet_stats_prev_.tl();
|
||||
stats->packets_total_ = packet_stats_total_.tl();
|
||||
stats->packets_total_->ts_start_ = (double)Adnl::adnl_start_time();
|
||||
stats->packets_total_->ts_end_ = td::Clocks::system();
|
||||
promise.set_result(std::move(stats));
|
||||
}
|
||||
|
||||
void AdnlLocalId::add_decrypted_packet_stats(td::IPAddress addr) {
|
||||
prepare_packet_stats();
|
||||
++packet_stats_cur_.decrypted_packets[addr];
|
||||
++packet_stats_total_.decrypted_packets[addr];
|
||||
}
|
||||
|
||||
void AdnlLocalId::add_dropped_packet_stats(td::IPAddress addr) {
|
||||
prepare_packet_stats();
|
||||
++packet_stats_cur_.dropped_packets[addr];
|
||||
++packet_stats_total_.dropped_packets[addr];
|
||||
}
|
||||
|
||||
void AdnlLocalId::prepare_packet_stats() {
|
||||
double now = td::Clocks::system();
|
||||
if (now >= packet_stats_cur_.ts_end) {
|
||||
packet_stats_prev_ = std::move(packet_stats_cur_);
|
||||
packet_stats_cur_ = {};
|
||||
auto now_int = (int)td::Clocks::system();
|
||||
packet_stats_cur_.ts_start = (double)(now_int / 60 * 60);
|
||||
packet_stats_cur_.ts_end = packet_stats_cur_.ts_start + 60.0;
|
||||
if (packet_stats_prev_.ts_end < now - 60.0) {
|
||||
packet_stats_prev_ = {};
|
||||
packet_stats_prev_.ts_end = packet_stats_cur_.ts_start;
|
||||
packet_stats_prev_.ts_start = packet_stats_prev_.ts_end - 60.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tl_object_ptr<ton_api::adnl_stats_localIdPackets> AdnlLocalId::PacketStats::tl() const {
|
||||
auto obj = create_tl_object<ton_api::adnl_stats_localIdPackets>();
|
||||
obj->ts_start_ = ts_start;
|
||||
obj->ts_end_ = ts_end;
|
||||
for (const auto &[ip, packets] : decrypted_packets) {
|
||||
obj->decrypted_packets_.push_back(create_tl_object<ton_api::adnl_stats_ipPackets>(
|
||||
ip.is_valid() ? PSTRING() << ip.get_ip_str() << ":" << ip.get_port() : "", packets));
|
||||
}
|
||||
for (const auto &[ip, packets] : dropped_packets) {
|
||||
obj->dropped_packets_.push_back(create_tl_object<ton_api::adnl_stats_ipPackets>(
|
||||
ip.is_valid() ? PSTRING() << ip.get_ip_str() << ":" << ip.get_port() : "", packets));
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
} // namespace adnl
|
||||
|
||||
} // namespace ton
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue