Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Device test and update guide

## Target and connection

- The connected board is the `esp32s3_r8n8` environment on `COM3`.
- The router AP normally serves its authenticated portal at `http://192.168.4.1`.
- Preserve NVS: do not run `erase`, `erase_flash`, or any equivalent command unless explicitly asked. It contains the router, Wi-Fi, VLESS, and administrator configuration.

## Build and USB flash

Build with:

```powershell
pio run -e esp32s3_r8n8
```

Flash the built application through USB with:

```powershell
pio run -e esp32s3_r8n8 -t upload --upload-port COM3
```

If COM3 is busy, do not repeatedly retry or reset devices. First close PlatformIO/VS Code serial monitors and any other program using the port, then retry. USB upload normally preserves NVS.

## Linting and formatting

The repository formatting rules are in `.clang-format`. Before submitting C/C++ changes, check the affected files with:

```powershell
clang-format --dry-run --Werror --style=file src/main.c
```

To fix reported formatting violations, run:

```powershell
clang-format -i --style=file src/main.c
```

Replace `src/main.c` with every affected `.c` or `.h` file, then rerun the dry-run command. Formatting-only edits should not change behavior; validate them with the normal PlatformIO build when practical.

## Serial monitoring and diagnostics

Use 115200 baud. Open one monitor only:

```powershell
pio device monitor --port COM3 --baud 115200
```

At the firmware console, run `diag` twice about one second apart during a transfer. Record payload rates, smux sessions open/closed, EOF/socket/protocol close causes, smux wire bytes/frames, TCP receive-queue high-water/full counts, control timeouts, and free internal/PSRAM.

Close the monitor before uploading firmware; it holds COM3 exclusively.

## Web diagnostics and OTA

The authenticated status endpoint is `GET /api/config`; use Basic authentication supplied by the device owner. It includes the same smux and bandwidth counters as `diag` and can be sampled before/after a test.

Builds create an application-only OTA image at `dist/esp32-vless-router-esp32s3_r8n8-ota.bin`. Upload it through the portal's Firmware update section or authenticated `POST /api/ota` with `Content-Type: application/octet-stream`.

Use OTA only when the image fits the inactive OTA partition. If the portal reports that the image is too large, do not retry; use USB flashing instead. Never upload the merged `dist/...r8n8.bin` image through `/api/ota`.
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,23 @@ IP (`apip`), VLESS profile (`vless` or `vless-uri`), DNS resolver (`dns`),
multiplexing (`mux`), and portal password (`admin`). It never prints saved
passwords or the VLESS UUID.

For throughput diagnosis, start a speed test and enter `diag` twice about one
second apart. It reports the payload upload/download rate, STA RSSI and channel,
AP client count, TCP window/buffer configuration, UDP/smux queue pressure,
dropped datagrams, free internal/PSRAM, smux wire bytes/frames, and smux close
causes (EOF, socket error, or protocol error). A non-zero TCP receive-queue
`full` counter means one downstream client stream was too slow; it is now
closed independently rather than tearing down the shared smux session. The firmware uses 32 KiB TCP
receive/send buffers, SACK, 32 Wi-Fi TX buffers, and disables STA modem sleep;
the previous 5,760-byte TCP windows could limit a VLESS TCP stream to roughly
1 Mbps at high RTT. Use `route direct` for a same-boot,
non-VLESS comparison against a China speed-test server, then `route vless` to
return to the tunnel. **Direct mode sends TCP and UDP to the upstream network
without VLESS protection** and resets to VLESS on reboot.

If the USB console is unavailable, the authenticated local portal exposes the
same temporary route test: `POST /api/route` with `mode=direct` or `mode=vless`.

After flashing, join the setup AP and visit the AP gateway at `http://192.168.4.1` by default. Configure the router AP, downstream subnet by setting the ESP32 gateway IP, upstream Wi-Fi, and VLESS profile independently. Do not commit a configured `sdkconfig`, NVS dump, URI, UUID, or Wi-Fi password to a public repository.

For browser-only flashing, every build creates a target-specific image such as `dist/esp32-vless-router-esp32s3_r8n16.bin` or `dist/esp32-vless-router-esp32s3_r8n8.bin`. Follow [Browser-based flashing](docs/WEB_FLASHING.md) to program the image matching your board at address `0x0` using esptool-js. This full image installs the target's OTA partition table and can clear saved configuration; record the router settings first.
Expand Down
17 changes: 17 additions & 0 deletions sdkconfig.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,28 @@ CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=65536
CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10
CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=64
CONFIG_ESP_WIFI_RX_BA_WIN=6
CONFIG_ESP_WIFI_STATIC_TX_BUFFER_NUM=32
CONFIG_ESP_WIFI_CACHE_TX_BUFFER_NUM=64
CONFIG_LWIP_MAX_SOCKETS=120
CONFIG_LWIP_DHCPS_MAX_STATION_NUM=16
# CONFIG_LWIP_IPV6 is not set
CONFIG_LWIP_MAX_ACTIVE_TCP=128
CONFIG_LWIP_MAX_LISTENING_TCP=64
CONFIG_LWIP_TCP_SND_BUF_DEFAULT=32768
CONFIG_LWIP_TCP_WND_DEFAULT=32768
CONFIG_LWIP_TCP_RECVMBOX_SIZE=32
CONFIG_LWIP_TCP_ACCEPTMBOX_SIZE=32
CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4
CONFIG_LWIP_TCP_SACK_OUT=y
# ESP32-S3 maximum fixed CPU clock; power management is disabled for router latency.
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
# This is a forwarding appliance, not a source-level debug build. -O2 removes
# substantial relay-path overhead compared with ESP-IDF's default -Og.
CONFIG_COMPILER_OPTIMIZATION_PERF=y
# Compile out Info-level logging. VLESS_TRAFFIC_LOGS is also off by default;
# serial `diag` deliberately uses warning level and remains available.
CONFIG_LOG_DEFAULT_LEVEL_WARN=y
CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y
# Per-core runtime measurements used by the authenticated diagnostics UI.
CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y
CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID=y
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
idf_component_register(SRCS "main.c" "router_config.c" "status_led.c" "portal_page.c"
"transport_tcp.c"
"transparent_tcp.c" "xudp_codec.c" "singmux_codec.c"
REQUIRES esp_wifi esp_netif esp_event nvs_flash esp_http_server lwip esp_driver_rmt app_update)
REQUIRES esp_wifi esp_netif esp_event nvs_flash esp_http_server lwip esp_driver_rmt esp_driver_tsens app_update)
Loading
Loading