Skip to content

Network stack never recovers without a hard reset after receiving closely-spaced larger UDP packets #2899

Closed
@ssilverman

Description

@ssilverman

Hardware:

Board: Adafruit ESP32 Feather
Core Installation version: Core v1.0.2 in Arduino 1.8.9, espressif32@1.8.0 and framework-arduinoespressif32@2.10002.190416 in PlatformIO
IDE name: Arduino v1.8.9 and PlatformIO v3.6.7 in VSCode v1.35.1
Flash Frequency: 80MHz
PSRAM enabled: Don't know
Upload Speed: 921600
Computer OS: Mac OSX v10.14.5

Description:

The network stack never recovers if it receives just tens of larger UDP packets greater than 1024 bytes. This detail got lost in the discussion of #2871, so I'm creating this new bug.

I see this problem almost every time I send somewhere between 20-80 larger UDP packets in non-softAP mode. I see this problem sometimes but rarely when using softAP mode. Sometimes, if I repeatedly run the program, see the network stack crash, and then hard reset the device, I won't see the network stack failure and it will recover from seeing a bunch of large packets. But only sometimes.

To reiterate: The network stack does not recover after receiving a bunch of large packets. Some people see that it recovers just fine if the packets stop, but I never see this. Yes, the device stops seeing packets if it's flooded with them, and yes, some people will see the network stack recover after a short period, but I never do. A hard reset is required.

To continuously send closely-spaced packets, this Bash script is useful:

while true; do echo -n $(printf '.%.0s' {1..1400}) > /dev/udp/192.168.1.9/8000; sleep 0.05; done

The 1400 is the UDP size; I find that 1025 and greater causes the problem for me. Also, change the IP address and sleep (in seconds) to play with different network loads.

The crux is this: I see onPacket never called again once a bunch of large packets are received, even if no more packets are sent. I've tried on three different ESP32 Feathers and three different network setups for non-softAP mode.

The effect: The device becomes permanently unusable on the network, without a hard reset, if it sees lots of larger UDP packets in a row.

Sketch:

#include <AsyncUDP.h>
#include <Esp.h>
#include <WiFi.h>

constexpr char kAPName[] = "ChangeMe";
constexpr char kAPPassword[] = "ChangeMe";
constexpr bool isSoftAP = false;  // Change to true for SoftAP mode

AsyncUDP udp;

void setup() {
  Serial.begin(115200);
  while (!Serial && millis() < 4000) {
    // Wait for Serial
  }
  Serial.println("Starting.");

  if (isSoftAP) {
    Serial.println("Starting SoftAP...");
    if (WiFi.softAP(kAPName, kAPPassword)) {
      Serial.print("    IP: ");
      Serial.println(WiFi.softAPIP());
    } else {
      Serial.println("ERROR: Starting SoftAP!");
    }
  } else {
    if (WiFi.begin(kAPName, kAPPassword)) {
      while (!WiFi.isConnected()) {
        delay(500);
      }
      Serial.print("    IP: ");
      Serial.println(WiFi.localIP());
      Serial.print("    Subnet: ");
      Serial.println(WiFi.subnetMask());
      Serial.print("    Gateway: ");
      Serial.println(WiFi.gatewayIP());
    } else {
      Serial.println("    ERROR: Connecting to AP!");
    }
  }

  if (!udp.listen(8000)) {
    Serial.println("ERROR: Starting UDP server!");
  }
  udp.onPacket(onPacket);
}

int counter = 0;

void onPacket(AsyncUDPPacket &packet) {
  Serial.printf("%d: %d\n", ++counter, packet.length());
}

void loop() {
  // Print some status every 5s
  Serial.printf("Free heap: %d\n", ESP.getFreeHeap());
  delay(5000);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Status: StaleIssue is stale stage (outdated/stuck)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions