Cleanup packet statistics
This commit is contained in:
parent
27b75b83de
commit
983af5cf3e
|
@ -2072,8 +2072,8 @@ void TunsafeBackendWin32::CollectStats() {
|
|||
stats_ = runner_->wg_proc_.GetStats();
|
||||
float data[2] = {
|
||||
// unit is megabits/second
|
||||
stats_.tun_bytes_in_per_second * (1.0f / 125000),
|
||||
stats_.tun_bytes_out_per_second * (1.0f / 125000),
|
||||
stats_.data_bytes_out_per_second * (1.0f / 125000),
|
||||
stats_.data_bytes_in_per_second * (1.0f / 125000),
|
||||
};
|
||||
stats_collector_.AddSamples(data);
|
||||
stats_mutex_.Release();
|
||||
|
|
|
@ -163,14 +163,14 @@ public:
|
|||
InvalidatePaintbox();
|
||||
|
||||
char buf[64];
|
||||
uint32 mbs_in = (uint32)(stats.tun_bytes_out_per_second * (1.0 / 1250));
|
||||
uint32 gb_in = (uint32)(stats.tun_bytes_out * (1.0 / (1024 * 1024 * 1024 / 100)));
|
||||
uint32 mbs_in = (uint32)(stats.data_bytes_in_per_second * (1.0 / 1250));
|
||||
uint32 gb_in = (uint32)(stats.data_bytes_in * (1.0 / (1024 * 1024 * 1024 / 100)));
|
||||
|
||||
snprintf(buf, ARRAYSIZE(buf), "D: %d.%.2d Mbps (%d.%.2d GB)", mbs_in / 100, mbs_in % 100, gb_in / 100, gb_in % 100);
|
||||
SendMessage(hwndStatus, SB_SETTEXT, 1, (LPARAM)buf);
|
||||
|
||||
uint32 mbs_out = (uint32)(stats.tun_bytes_in_per_second * (1.0 / 1250));
|
||||
uint32 gb_out = (uint32)(stats.tun_bytes_in * (1.0 / (1024 * 1024 * 1024 / 100)));
|
||||
uint32 mbs_out = (uint32)(stats.data_bytes_out_per_second * (1.0 / 1250));
|
||||
uint32 gb_out = (uint32)(stats.data_bytes_out * (1.0 / (1024 * 1024 * 1024 / 100)));
|
||||
|
||||
snprintf(buf, ARRAYSIZE(buf), "U: %d.%.2d Mbps (%d.%.2d GB)", mbs_out / 100, mbs_out % 100, gb_out / 100, gb_out % 100);
|
||||
SendMessage(hwndStatus, SB_SETTEXT, 2, (LPARAM)buf);
|
||||
|
@ -1521,6 +1521,7 @@ static const AdvancedTextInfo ADVANCED_TEXT_INFOS[] = {
|
|||
{Y + 19 * 4, 66, ""},
|
||||
{Y + 19 * 5, 66, "Overhead:"},
|
||||
{Y + 19 * 6, 66, "Packet Loss:"},
|
||||
{Y + 19 * 7, 66, "Invalid:"},
|
||||
#undef Y
|
||||
};
|
||||
|
||||
|
@ -1576,8 +1577,8 @@ static const char *GetAdvancedInfoValue(char buffer[256], int i) {
|
|||
|
||||
case 2:
|
||||
snprintf(buffer, 256, "%s in (%lld packets), %s out (%lld packets)",
|
||||
PrintMB(tmp, ps->udp_bytes_in), ps->udp_packets_in,
|
||||
PrintMB(tmp2, ps->udp_bytes_out), ps->udp_packets_out/*, udp_qsize2 - udp_qsize1, g_tun_reads*/);
|
||||
PrintMB(tmp, ps->total_bytes_in), ps->packets_in,
|
||||
PrintMB(tmp2, ps->total_bytes_out), ps->packets_out/*, udp_qsize2 - udp_qsize1, g_tun_reads*/);
|
||||
return buffer;
|
||||
case 3: return PrintLastHandshakeAt(buffer, ps);
|
||||
case 4: {
|
||||
|
@ -1587,11 +1588,11 @@ static const char *GetAdvancedInfoValue(char buffer[256], int i) {
|
|||
return buffer;
|
||||
}
|
||||
case 5: {
|
||||
uint64 overhead_in = ps->udp_bytes_in + ps->udp_packets_in * 40 - ps->tun_bytes_out;
|
||||
uint32 overhead_in_pct = ps->tun_bytes_out ? (uint32)(overhead_in * 100000 / ps->tun_bytes_out) : 0;
|
||||
uint64 overhead_in = ps->total_bytes_in + ps->packets_in * 40 - ps->data_bytes_in;
|
||||
uint32 overhead_in_pct = ps->data_bytes_in ? (uint32)(overhead_in * 100000 / ps->data_bytes_in) : 0;
|
||||
|
||||
uint64 overhead_out = ps->udp_bytes_out + ps->udp_packets_out * 40 - ps->tun_bytes_in;
|
||||
uint32 overhead_out_pct = ps->tun_bytes_in ? (uint32)(overhead_out * 100000 / ps->tun_bytes_in) : 0;
|
||||
uint64 overhead_out = ps->total_bytes_out + ps->packets_out * 40 - ps->data_bytes_out;
|
||||
uint32 overhead_out_pct = ps->data_bytes_out ? (uint32)(overhead_out * 100000 / ps->data_bytes_out) : 0;
|
||||
|
||||
snprintf(buffer, 256, "%d.%.3d%% in, %d.%.3d%% out", overhead_in_pct / 1000, overhead_in_pct % 1000,
|
||||
overhead_out_pct / 1000, overhead_out_pct % 1000);
|
||||
|
@ -1603,6 +1604,10 @@ static const char *GetAdvancedInfoValue(char buffer[256], int i) {
|
|||
(int)(ps->lost_packets_tot - ps->lost_packets_valid));
|
||||
return buffer;
|
||||
}
|
||||
case 7: {
|
||||
snprintf(buffer, 256, "%s in (%lld packets)", PrintMB(tmp, ps->invalid_bytes_in), ps->invalid_packets_in);
|
||||
return buffer;
|
||||
}
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -344,8 +344,6 @@ void WireguardProcessor::HandleTunPacket(Packet *packet) {
|
|||
void WireguardProcessor::HandleUdpPacket(Packet *packet, bool overload) {
|
||||
PacketResult result = HandleUdpPacket2(packet, overload);
|
||||
if (result == kPacketResult_ForwardTun) {
|
||||
//stats_.tun_bytes_out += size_from_header;
|
||||
//stats_.tun_packets_out++;
|
||||
tun_->WriteTunPacket(packet);
|
||||
} else if (result == kPacketResult_ForwardUdp) {
|
||||
udp_->WriteUdpPacket(packet);
|
||||
|
@ -441,9 +439,6 @@ WireguardProcessor::PacketResult WireguardProcessor::WriteAndEncryptPacketToUdp_
|
|||
}
|
||||
assert(!peer->marked_for_delete_);
|
||||
|
||||
stats_.tun_bytes_in += size;
|
||||
stats_.tun_packets_in++;
|
||||
|
||||
want_handshake = (send_ctr >= REKEY_AFTER_MESSAGES ||
|
||||
keypair->send_key_state == WgKeypair::KEY_WANT_REFRESH);
|
||||
keypair->send_ctr = send_ctr + 1;
|
||||
|
@ -563,8 +558,9 @@ need_big_packet:
|
|||
if (want_handshake)
|
||||
peer->ScheduleNewHandshake();
|
||||
|
||||
stats_.udp_packets_out++;
|
||||
stats_.udp_bytes_out += packet->size;
|
||||
stats_.packets_out++;
|
||||
stats_.data_bytes_out += orig_size;
|
||||
stats_.total_bytes_out += packet->size;
|
||||
|
||||
return kPacketResult_ForwardUdp;
|
||||
|
||||
|
@ -577,8 +573,8 @@ void WireguardProcessor::PrepareOutgoingHandshakePacket(WgPeer *peer, Packet *pa
|
|||
assert(dev_.IsMainThread());
|
||||
if (dev_.plugin_)
|
||||
dev_.plugin_->OnOutgoingHandshakePacket(peer, packet);
|
||||
stats_.udp_packets_out++;
|
||||
stats_.udp_bytes_out += packet->size;
|
||||
stats_.packets_out++;
|
||||
stats_.total_bytes_out += packet->size;
|
||||
}
|
||||
|
||||
void WireguardProcessor::RunAllMainThreadScheduled() {
|
||||
|
@ -666,9 +662,6 @@ WireguardProcessor::PacketResult WireguardProcessor::HandleUdpPacket2(Packet *pa
|
|||
uint32 type;
|
||||
assert(packet->protocol != 0xCD && (uint16)packet->addr.sin.sin_family != 0xCDCD); // catch msvc uninit mem
|
||||
|
||||
stats_.udp_bytes_in += packet->size;
|
||||
stats_.udp_packets_in++;
|
||||
|
||||
if (packet->size < sizeof(uint32))
|
||||
goto invalid_size;
|
||||
type = ReadLE32((uint32*)packet->data);
|
||||
|
@ -707,6 +700,8 @@ WireguardProcessor::PacketResult WireguardProcessor::HandleUdpPacket2(Packet *pa
|
|||
} else {
|
||||
// unknown packet
|
||||
invalid_size:
|
||||
stats_.invalid_packets_in++;
|
||||
stats_.invalid_bytes_in += packet->size;
|
||||
return kPacketResult_Free;
|
||||
}
|
||||
}
|
||||
|
@ -819,8 +814,7 @@ WireguardProcessor::PacketResultd WireguardProcessor::HandleShortHeaderFormatPac
|
|||
keypair->can_use_short_key_for_outgoing = (ack_tag & WG_ACK_HEADER_KEY_MASK) * WG_SHORT_HEADER_KEY_ID;
|
||||
|
||||
packet->data = data;
|
||||
packet->size = bytes_left - keypair->auth_tag_length;
|
||||
return HandleAuthenticatedDataPacket_WillUnlock(keypair, packet);
|
||||
return HandleAuthenticatedDataPacket_WillUnlock(keypair, packet, bytes_left - keypair->auth_tag_length);
|
||||
getout_unlock:
|
||||
WG_RELEASE_LOCK(keypair->peer->mutex_);
|
||||
getout:
|
||||
|
@ -840,7 +834,7 @@ void WireguardProcessor::NotifyHandshakeComplete() {
|
|||
procdel_->OnConnected();
|
||||
}
|
||||
|
||||
WireguardProcessor::PacketResult WireguardProcessor::HandleAuthenticatedDataPacket_WillUnlock(WgKeypair *keypair, Packet *packet) {
|
||||
WireguardProcessor::PacketResult WireguardProcessor::HandleAuthenticatedDataPacket_WillUnlock(WgKeypair *keypair, Packet *packet, uint data_size) {
|
||||
WgPeer *peer = keypair->peer;
|
||||
assert(peer->IsPeerLocked());
|
||||
assert(packet->addr.sin.sin_family != 0);
|
||||
|
@ -865,7 +859,7 @@ WireguardProcessor::PacketResult WireguardProcessor::HandleAuthenticatedDataPack
|
|||
}
|
||||
}
|
||||
|
||||
WG_EXTENSION_HOOKS::OnPeerIncomingUdp(peer, packet);
|
||||
WG_EXTENSION_HOOKS::OnPeerIncomingUdp(peer, packet, data_size);
|
||||
|
||||
// Remember how many incoming packets we've seen so we can approximate loss
|
||||
keypair->incoming_packet_count++;
|
||||
|
@ -886,11 +880,12 @@ WireguardProcessor::PacketResult WireguardProcessor::HandleAuthenticatedDataPack
|
|||
peer->ScheduleNewHandshake();
|
||||
}
|
||||
|
||||
uint32 data_size = packet->size;
|
||||
if (data_size == 0) {
|
||||
peer->OnKeepaliveReceived();
|
||||
WG_RELEASE_LOCK(peer->mutex_);
|
||||
goto getout;
|
||||
stats_.packets_in++;
|
||||
stats_.total_bytes_in += packet->size;
|
||||
return kPacketResult_Free;
|
||||
}
|
||||
peer->OnDataReceived();
|
||||
WG_RELEASE_LOCK(peer->mutex_);
|
||||
|
@ -899,7 +894,7 @@ WireguardProcessor::PacketResult WireguardProcessor::HandleAuthenticatedDataPack
|
|||
if (WITH_PACKET_COMPRESSION && keypair->compress_handler_) {
|
||||
WgCompressHandler::CompressState st = keypair->compress_handler_->Decompress(packet);
|
||||
if (st == WgCompressHandler::COMPRESS_FAIL)
|
||||
goto getout;
|
||||
goto getout_error_header;
|
||||
if (st == WgCompressHandler::COMPRESS_YES)
|
||||
stats_.compression_hdr_saved_in += (int32)(packet->size - exch(data_size, packet->size));
|
||||
}
|
||||
|
@ -943,13 +938,18 @@ WireguardProcessor::PacketResult WireguardProcessor::HandleAuthenticatedDataPack
|
|||
if (size_from_header > data_size)
|
||||
goto getout_error_header;
|
||||
|
||||
stats_.packets_in++;
|
||||
stats_.data_bytes_in += size_from_header;
|
||||
stats_.total_bytes_in += packet->size;
|
||||
|
||||
packet->size = size_from_header;
|
||||
|
||||
return kPacketResult_ForwardTun;
|
||||
|
||||
getout_error_header:
|
||||
stats_.error_header++;
|
||||
getout:
|
||||
stats_.invalid_packets_in++;
|
||||
stats_.invalid_bytes_in += packet->size;
|
||||
return kPacketResult_Free;
|
||||
}
|
||||
|
||||
|
@ -964,11 +964,13 @@ WireguardProcessor::PacketResult WireguardProcessor::HandleDataPacket(Packet *pa
|
|||
if (keypair == NULL || counter >= REJECT_AFTER_MESSAGES) {
|
||||
stats_.error_key_id++;
|
||||
getout:
|
||||
stats_.invalid_packets_in++;
|
||||
stats_.invalid_bytes_in += data_size;
|
||||
return kPacketResult_Free;
|
||||
}
|
||||
|
||||
packet->data = data + sizeof(MessageData);
|
||||
packet->size = data_size - sizeof(MessageData) - keypair->auth_tag_length;
|
||||
uint32 data_size_after = data_size - sizeof(MessageData) - keypair->auth_tag_length;
|
||||
|
||||
if (!WgKeypairDecryptPayload(data + sizeof(MessageData), data_size - sizeof(MessageData),
|
||||
NULL, 0, counter, keypair)) {
|
||||
|
@ -988,7 +990,7 @@ getout:
|
|||
goto getout;
|
||||
} else {
|
||||
assert(!keypair->peer->marked_for_delete_);
|
||||
return HandleAuthenticatedDataPacket_WillUnlock(keypair, packet);
|
||||
return HandleAuthenticatedDataPacket_WillUnlock(keypair, packet, data_size_after);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1003,8 +1005,12 @@ static uint64 GetIpForRateLimit(Packet *packet) {
|
|||
WireguardProcessor::PacketResult WireguardProcessor::CheckIncomingHandshakeRateLimit(Packet *packet, bool overload) {
|
||||
assert(dev_.IsMainThread());
|
||||
WgRateLimit::RateLimitResult rr = dev_.rate_limiter()->CheckRateLimit(GetIpForRateLimit(packet));
|
||||
if ((overload && rr.is_rate_limited()) || !dev_.CheckCookieMac1(packet))
|
||||
|
||||
if ((overload && rr.is_rate_limited()) || !dev_.CheckCookieMac1(packet)) {
|
||||
stats_.invalid_packets_in++;
|
||||
stats_.invalid_bytes_in += packet->size;
|
||||
return kPacketResult_Free;
|
||||
}
|
||||
|
||||
dev_.rate_limiter()->CommitResult(rr);
|
||||
if (overload && !rr.is_first_ip() && !dev_.CheckCookieMac2(packet)) {
|
||||
|
@ -1021,11 +1027,20 @@ WireguardProcessor::PacketResult WireguardProcessor::CheckIncomingHandshakeRateL
|
|||
// server receives this when client wants to setup a session
|
||||
WireguardProcessor::PacketResult WireguardProcessor::HandleHandshakeInitiationPacket(Packet *packet) {
|
||||
assert(dev_.IsMainThread());
|
||||
uint original_size = packet->size;
|
||||
WgPeer *peer = WgPeer::ParseMessageHandshakeInitiation(&dev_, packet);
|
||||
if (peer) {
|
||||
PrepareOutgoingHandshakePacket(peer, packet);
|
||||
|
||||
stats_.packets_in++;
|
||||
stats_.packets_out++;
|
||||
stats_.total_bytes_in += original_size;
|
||||
stats_.total_bytes_out += packet->size;
|
||||
|
||||
return kPacketResult_ForwardUdp;
|
||||
} else {
|
||||
stats_.invalid_packets_in++;
|
||||
stats_.invalid_bytes_in += original_size;
|
||||
return kPacketResult_Free;
|
||||
}
|
||||
}
|
||||
|
@ -1033,14 +1048,21 @@ WireguardProcessor::PacketResult WireguardProcessor::HandleHandshakeInitiationPa
|
|||
// client receives this after session is established
|
||||
WireguardProcessor::PacketResult WireguardProcessor::HandleHandshakeResponsePacket(Packet *packet) {
|
||||
assert(dev_.IsMainThread());
|
||||
uint original_size = packet->size;
|
||||
WgPeer *peer = WgPeer::ParseMessageHandshakeResponse(&dev_, packet);
|
||||
if (peer) {
|
||||
stats_.packets_in++;
|
||||
stats_.total_bytes_in += original_size;
|
||||
|
||||
stats_.handshakes_out_success++;
|
||||
WG_SCOPED_LOCK(peer->mutex_);
|
||||
peer->OnHandshakeAuthComplete();
|
||||
peer->OnHandshakeFullyComplete();
|
||||
NotifyHandshakeComplete();
|
||||
SendKeepalive_Locked(peer);
|
||||
} else {
|
||||
stats_.invalid_packets_in++;
|
||||
stats_.invalid_bytes_in += original_size;
|
||||
}
|
||||
return kPacketResult_Free;
|
||||
}
|
||||
|
@ -1093,19 +1115,16 @@ void WireguardProcessor::SecondLoop() {
|
|||
assert(dev_.IsMainThread());
|
||||
uint64 now = OsGetMilliseconds();
|
||||
|
||||
uint64 bytes_in = stats_.tun_bytes_in - stats_last_bytes_in_;
|
||||
uint64 bytes_out = stats_.tun_bytes_out - stats_last_bytes_out_;
|
||||
|
||||
stats_last_bytes_in_ = stats_.tun_bytes_in;
|
||||
stats_last_bytes_out_ = stats_.tun_bytes_out;
|
||||
uint64 bytes_out = stats_.data_bytes_out - exch(stats_last_bytes_out_, stats_.data_bytes_out);
|
||||
uint64 bytes_in = stats_.data_bytes_in - exch(stats_last_bytes_in_, stats_.data_bytes_in);
|
||||
|
||||
uint64 millis = now - stats_last_ts_;
|
||||
stats_last_ts_ = now;
|
||||
|
||||
double f = 1000.0 / std::max<uint32>((uint32)millis, 500);
|
||||
|
||||
stats_.tun_bytes_in_per_second = (float)(bytes_in * f);
|
||||
stats_.tun_bytes_out_per_second = (float)(bytes_out * f);
|
||||
stats_.data_bytes_out_per_second = (float)(bytes_out * f);
|
||||
stats_.data_bytes_in_per_second = (float)(bytes_in * f);
|
||||
|
||||
for (WgPeer *peer = dev_.first_peer(); peer; peer = peer->next_peer_) {
|
||||
WgKeypair *keypair = peer->curr_keypair_;
|
||||
|
|
22
wireguard.h
22
wireguard.h
|
@ -7,13 +7,17 @@
|
|||
|
||||
// todo: for multithreaded use case need to use atomic ops.
|
||||
struct WgProcessorStats {
|
||||
// Number of bytes sent/received over the physical UDP connection
|
||||
uint64 udp_bytes_in, udp_bytes_out;
|
||||
uint64 udp_packets_in, udp_packets_out;
|
||||
// The amount of authenticated data received over the wireguard connection.
|
||||
uint64 packets_in, data_bytes_in, total_bytes_in;
|
||||
|
||||
// The amount of authenticated data sent across the wireguard connection.
|
||||
// |data_bytes_out| holds the actual bytes, while |total_bytes_out|
|
||||
// includes wireguard overhead.
|
||||
uint64 packets_out, data_bytes_out, total_bytes_out;
|
||||
|
||||
// The amount of invalid data received from the network
|
||||
uint64 invalid_packets_in, invalid_bytes_in;
|
||||
|
||||
// Number of valid packets sent/received over the TUN interface
|
||||
uint64 tun_bytes_in, tun_bytes_out;
|
||||
uint64 tun_packets_in, tun_packets_out;
|
||||
|
||||
// Error types
|
||||
uint32 error_key_id;
|
||||
|
@ -22,8 +26,8 @@ struct WgProcessorStats {
|
|||
uint32 error_source_addr;
|
||||
uint32 error_header;
|
||||
|
||||
// Current speed of TUN packets
|
||||
float tun_bytes_in_per_second, tun_bytes_out_per_second;
|
||||
// Current speed
|
||||
float data_bytes_out_per_second, data_bytes_in_per_second;
|
||||
|
||||
// Timestamp of handshakes
|
||||
uint64 first_complete_handshake_timestamp;
|
||||
|
@ -143,7 +147,7 @@ private:
|
|||
PacketResult HandleHandshakeCookiePacket(Packet *packet);
|
||||
PacketResult HandleDataPacket(Packet *packet);
|
||||
|
||||
PacketResult HandleAuthenticatedDataPacket_WillUnlock(WgKeypair *keypair, Packet *packet);
|
||||
PacketResult HandleAuthenticatedDataPacket_WillUnlock(WgKeypair *keypair, Packet *packet, uint data_size);
|
||||
PacketResult HandleShortHeaderFormatPacket(uint32 tag, Packet *packet);
|
||||
PacketResult CheckIncomingHandshakeRateLimit(Packet *packet, bool overload);
|
||||
bool HandleIcmpv6NeighborSolicitation(const byte *data, size_t data_size);
|
||||
|
|
|
@ -794,7 +794,7 @@ WgPeer *WgPeer::ParseMessageHandshakeResponse(WgDevice *dev, const Packet *packe
|
|||
peer->data_endpoint_ = peer->endpoint_;
|
||||
}
|
||||
|
||||
WG_EXTENSION_HOOKS::OnPeerIncomingUdp(peer, packet);
|
||||
WG_EXTENSION_HOOKS::OnPeerIncomingUdp(peer, packet, packet->size);
|
||||
|
||||
peer->rx_bytes_ += packet->size;
|
||||
peer->InsertKeypairInPeer_Locked(keypair);
|
||||
|
|
|
@ -819,7 +819,7 @@ bool WgKeypairDecryptPayload(uint8 *dst, const size_t src_len,
|
|||
|
||||
struct WgExtensionHooksDefault {
|
||||
static uint32 GetIpv4Target(Packet *packet, uint8 *data) { return ReadBE32(data + 16); }
|
||||
static void OnPeerIncomingUdp(WgPeer *peer, const Packet *packet) { }
|
||||
static void OnPeerIncomingUdp(WgPeer *peer, const Packet *packet, uint data_size) { }
|
||||
static void OnPeerOutgoingUdp(WgPeer *peer, Packet *packet) { }
|
||||
static bool DisableSourceAddressVerification(WgPeer *peer) { return false; }
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue