openwrt / openwrt/packages

v2raya: OOM during TProxy GeoIP whitelist parsing; orphaned Xray blocks port 20171

Open
#30,285 8 comments 1 reaction 1 assignee View on GitHub

@1715173329 is already working on this.

Since Aug 17, 2026.

bug
Dominant language
Makefile
Stars
4.6k
Forks
4k
Avg merge
3d 12h
Merged PRs (30d)
134

Description

Package Name

v2raya (2.2.7.5-r1)

Maintainer

@1715173329 (Tianling Shen)

OpenWrt Version

SNAPSHOT r35820-964c05aee9

OpenWrt Target/Subtarget

mediatek/filogic

Steps to Reproduce
  1. Install the official OpenWrt v2raya 2.2.7.5-r1 package and Xray-core 26.3.27-r1.
  2. Enable transparent proxy using TProxy.
  3. Select "Do not Split Traffic".
  4. Keep the default PRIVATE direct-whitelist IP group.
  5. Start/connect v2rayA.
  6. Observe v2rayA RSS and the kernel log while transparent-proxy rules are generated.

Environment:

  • Device: COMFAST CF-WR632AX (UBI), 512 MiB RAM, aarch64/MediaTek Filogic
  • Kernel: 6.18.44
  • v2rayA: 2.2.7.5-r1, built with Go 1.26.6
  • Xray-core: 26.3.27-r1
  • geoip.dat: 23,080,744 bytes
  • geoip.dat SHA-256: c67bd077eb102cec74fab759b73d17f99275f56af10a87c14d9fd983508f5ce1
Actual Behaviour

v2raya rapidly grows to about 355 MiB RSS until the global OOM killer terminates it:

Out of memory: Killed process 2625 (v2raya) total-vm:1632392kB,
anon-rss:354808kB, file-rss:0kB, shmem-rss:0kB

The Xray child survives, is reparented to PID 1, and keeps the API/proxy ports. The OpenWrt init script has procd_set_param respawn, so procd starts a new v2rayA parent, but the new instance cannot start Xray:

failed to start v2ray-core: port is occupied by xray(2857): 20171
Root cause

A Go stack captured near the memory peak shows:

google.golang.org/protobuf/proto.Unmarshal
github.com/v2rayA/v2rayA/common/parseGeoIP.Parser (parser.go:27)
github.com/v2rayA/v2rayA/core/iptables.GetWhiteListIPs (utils.go:101)
github.com/v2rayA/v2rayA/core/iptables.IsEnabledTproxyWhiteIpGroups
github.com/v2rayA/v2rayA/core/iptables.(*nftTproxy).GetSetupCommands
github.com/v2rayA/v2rayA/core/v2ray.writeTransparentProxyRules

GC tracing showed the heap repeatedly expanding to roughly 160-183 MiB. The packaged upstream version reads all of geoip.dat with os.ReadFile and runs proto.Unmarshal into the complete GeoIPList on every parseGeoIP.Parser call. GetWhiteListIPs() is called several times during TProxy rule generation, even when only the PRIVATE entry is needed.

This is primarily an upstream code issue, but the official OpenWrt package is currently pinned to the affected v2rayA 2.2.7.5 release, making the official package unsafe to start with this common configuration on memory-constrained routers.

Relevant package files:

Upstream report and tested fix

The upstream report, complete analysis, tested patch, and measurements are here:

The patch walks the top-level protobuf wire records with protowire, unmarshals one GeoIP entry at a time, stops at the requested country code, and caches results by asset path, size, modification time, and country code.

On the same router with the patched 2.2.7.5 binary:

  • TProxy initialization completes in about 2-3 seconds.
  • v2rayA remains stable at about 100 MiB RSS.
  • Xray remains around 24 MiB RSS.
  • More than 270 MiB remains available.
  • No additional OOM event occurs.
Expected behaviour
  • Enabling TProxy with the default PRIVATE whitelist must not trigger the global OOM killer on a 512 MiB router.
  • Only the requested top-level GeoIP entry should be decoded, or decoded results should be cached.
  • An unexpected v2rayA parent exit should not leave an orphaned Xray process blocking the respawned service's ports.
Requested OpenWrt package action
  1. Please consider backporting the tested parser patch under net/v2raya/patches/ and bumping PKG_RELEASE while the upstream fix is reviewed/released.
  2. Alternatively, coordinate the upstream fix and update the package as soon as a fixed release is available.
  3. Please review the independent child-process lifecycle issue. The parser patch removes the OOM trigger, but an unexpected parent death can still leave the owned Xray child alive while procd respawns only v2rayA.
Confirmation Checklist

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.