mirror of
https://github.com/esphome/esphome.git
synced 2026-10-21 13:34:12 +00:00
[udp] Drop datagrams longer than the receive buffer
A read cuts a datagram longer than the buffer to fit, so a 600 byte datagram arrived as a valid looking 508 byte packet. The buffer is now one byte longer, and a read that fills it is dropped. The split packet test also checks the bytes joined in the copy buffer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
f128049f99
commit
ef6bb95608
@@ -209,7 +209,8 @@ void UDPComponent::loop() {
|
||||
this->disable_loop();
|
||||
return;
|
||||
}
|
||||
std::array<uint8_t, MAX_PACKET_SIZE> buf;
|
||||
// One byte more than the largest packet, as a read cuts a longer datagram to fit and so cannot report it
|
||||
std::array<uint8_t, MAX_PACKET_SIZE + 1> buf;
|
||||
for (;;) {
|
||||
if (!this->listen_socket_->ready())
|
||||
break;
|
||||
@@ -217,6 +218,10 @@ void UDPComponent::loop() {
|
||||
if (len <= 0)
|
||||
break;
|
||||
size_t packet_len = static_cast<size_t>(len);
|
||||
if (packet_len > MAX_PACKET_SIZE) {
|
||||
ESP_LOGV(TAG, "Packet longer than %zu bytes dropped", MAX_PACKET_SIZE);
|
||||
continue;
|
||||
}
|
||||
ESP_LOGV(TAG, "Received packet of length %zu", packet_len);
|
||||
this->packet_listeners_.call(std::span<const uint8_t>(buf.data(), packet_len));
|
||||
}
|
||||
|
||||
@@ -56,6 +56,9 @@ TEST_F(UdpPacketInterfaceTest, SendsContiguousAndSplitPackets) {
|
||||
uint8_t header = 0;
|
||||
PacketBuffer body(packet);
|
||||
EXPECT_TRUE(this->link_.send_to_interface(PacketBuffer(&header, 1, &body, nullptr, 0), {}));
|
||||
// A packet split across buffers is joined in the copy buffer before it is sent
|
||||
const auto *storage = this->link_.tx_buffer_storage;
|
||||
EXPECT_EQ(Packet(storage, storage + 5), (Packet{0, 1, 2, 3, 4}));
|
||||
}
|
||||
|
||||
TEST_F(UdpPacketInterfaceTest, OversizedPacketNotSent) {
|
||||
|
||||
Reference in New Issue
Block a user