v0.2.0
XferRust v0.2.0 Release Notes
English | 简体中文
Summary: A magnet-experience and BT-stability release — pick which files to download from a table after a magnet link is parsed (download starts only after confirmation), plus fixes for a peer session leak, rate-limiter deadlock and uTP stream corruption, hardening against path traversal and metadata poisoning, and completed ut_metadata serving, tracker reporting and choking behavior. The TUI is fully redesigned as well — the add-task dialog supports a per-task download directory (with a native system folder picker), magnet links start parsing immediately and expand the dialog in place into a file-selection table once metadata is ready, the main layout is rebuilt into a modern flat design, and the global info bar stays visible on task detail pages. Additionally, this release adds full BT seeding lifecycle management (configurable share-ratio auto-stop, continuous seeding until manual stop) and Android platform engine-core cross-compilation support; it also completes BT network discoverability — local peer discovery (LPD), automatic UPnP/NAT-PMP port mapping and configurable BT/DHT listen ports — and fixes the tail-end stall that left HTTP/HTTPS downloads hanging at 99%.
New Features
- Magnet file selection: the engine starts parsing metadata as soon as a magnet link is added; once parsed, the task pauses and a file table is shown (checkbox, file size, selection summary), and only the checked files are downloaded. Pieces spanning the selected/unselected boundary are downloaded whole, as BitTorrent requires
- Magnet tasks are resumable: a task still waiting for file selection reopens the file table after a restart instead of silently downloading everything
- Serve ut_metadata (BEP 9) requests: magnet peers get proper DATA/REJECT responses instead of being ignored
seed_durationis now honored: seeding exits cleanly with a stopped announce when the configured time is up
BT Seeding Lifecycle Management
- BT tasks can be configured to enter a seeding state after download completion (instead of finishing immediately), controlled by the global option
bt-seed-mode(true/false) - Seeding tasks display a live share ratio (uploaded / downloaded); a target share ratio
bt-seed-ratio(e.g.1.5,2.0) can be set — seeding auto-stops when the ratio is reached - Seeding tasks can be paused/resumed, and seeding can be manually stopped (RPC
task.stopSeed/ TUISkey) - Continuous seeding until manual stop is supported (
bt-seed-ratioof0disables auto-stop) - TUI settings page adds seeding mode and target share ratio options; task list/detail views show upload speed and share ratio for seeding tasks
BT Network Discovery & Port Configuration
- Local peer discovery (LPD / BEP 14): each BT task joins the LSD multicast group, periodically announces to and listens on the LAN, so peers on the same network can find each other without trackers; discovered peers enter scheduling with an
lpdsource - Automatic UPnP / NAT-PMP port mapping: when a BT task starts, the engine sets up a TCP + UDP dual mapping on the router (2-hour lease, renewed every 1/3 of the lease, automatic retry next cycle after a single failure) and best-effort removes the mapping on shutdown — better connectability, no more manual router port forwarding
- Configurable BT / DHT listen ports: new global options
bt-listen-port/dht-listen-port(0= random port), applied when a BT task is created; if the listen port or DHT port is taken, the engine falls back to an ephemeral port with a warning instead of disabling listening entirely - New switches
bt-enable-lpd/bt-port-mapping(both on by default) to disable either feature independently;engine.getOptionsexposes the new options andchangeGlobalOptionvalidates port values (0–65535) - The TUI settings page gains the four matching rows: BT / DHT listen port (Enter to edit, validated 0–65535,
0shown as "random") plus Local discovery and Port mapping toggles (←/→ to switch); conns-per-server, min split size and language shift below them
Android Engine-Core Build
- Added Android (aarch64-linux-android / arm64-v8a) cross-compilation support — builds only the engine core (
xferrust), no TUI Cargo.tomlmakes TUI dependencies (crossterm, ratatui, etc.) optional under atuifeature;default = ["tui"]; thexferbinary is markedrequired-features = ["tui"]- CI adds a
build-androidjob: cross-compiles with NDK r27c + API 24 (Android 7.0+); artifactxferrust-android-arm64-v8a.tar.gzis included in releases - New local build script
scripts/build-android.sh: auto-detects NDK host-tag (macOS / Linux), sets CC/CXX/AR/Linker env vars and invokescargo build --no-default-features --bin xferrust
TUI Redesign
- Redesigned add-task dialog: URL + directory fields; an empty directory falls back to the global download directory (per task only). The directory can be typed manually or picked with the native system folder dialog by pressing Enter (macOS / Windows / Linux)
- Magnet links start parsing metadata immediately, no extra confirmation step; the dialog shows live parsing progress (connections / waiting / elapsed). Once metadata is ready, the dialog expands downward into a file-selection table: Space to toggle, A to select all/none, Enter to start downloading the selected files
- The download directory in Settings is also picked with the native system folder dialog
- Task detail pages (BT / non-BT) keep the global info bar at the top (brand logo + global speed / task counters) instead of hiding it
Bug Fixes
- Fix magnet tasks reporting an empty file list while downloading: metadata is back-filled as soon as it is ready, so
filesandnumPiecesare no longer zero - Fix magnet metadata being lost across restarts: the session persists the info dictionary and rebuilds the metadata from it, no need to re-fetch from peers
- Fix inbound peer session leak: passive connections were never unregistered, stalling their assigned pieces for up to 180 s
- Fix rate-limiter deadlock: token bucket guarantees at least one max-size block, limits below 16 KiB/s no longer freeze the connection
- Fix uTP stream corruption: read path applies back-pressure via channel capacity; write path buffers partially accepted bytes instead of dropping them
- Sanitize torrent paths (name / path segments) to prevent path-traversal writes outside the download directory
- Fix scheduler treating 0→0 throughput as a 100% decline — target connection count no longer collapses during cold start
- Fix choking algorithm: wall-clock rounds shared by all sessions, engine-level optimistic unchoke that actually reaches the lucky peer, round-robin uploads while seeding
- Fix tracker announces always reporting zero uploaded bytes (private-tracker ratio tracking works now)
- Fix UDP trackers never receiving stopped/completed events
- Fix HTTP/HTTPS downloads hanging at 99% for over ten seconds before finishing:
- Tail short reads (response body shorter than the requested range) now use a dedicated backoff curve (from 250 ms, capped at 1 s) instead of sharing the 0.5–2 s hard-failure backoff — short reads always make progress when retried from the watermark, and the old backoff accumulated into a long tail under retry storms
- New 10-second read-idle watchdog: a silently stalled connection (dead peer / half-open socket) resumes from the watermark immediately instead of waiting out the 30-second read timeout
- Read timeouts are now classified as renewable transients: they no longer consume the 4-strike failure budget, so tail retries are no longer killed prematurely
UI Redesign
- Flat top bar: a single row with the brand logo on the left and ↓/↑ global speed plus active/waiting/stopped counters on the right, separated by a vertical bar
- Square task-area borders: top/bottom lines start aligned with the logo, end in rounded corners joined to the right vertical line, all four corners left open; the sidebar/content divider leaves headroom above and below
- Sidebar: removed the category heading, selection is now highlighted with a background (no more pointer)
- Task table: a separator line between the header and rows (same color as the border, same width as the columns, symmetric on both sides); header and rows keep one column of padding on each side, symmetric left/right
- Size column is now a compact "completed / total" format, the speed column is narrower, and task names no longer push later columns out of alignment
Other Changes
- New file-selection API:
select_files(gid, file_indices)/get_selected_files(gid), applied live on running tasks;add_uriaccepts abt-file-selectionoption to pause a magnet task after parsing and wait for a selection - Task status exposes a new
awaitingSelectionfield, andfiles[].selectednow reflects the real selection - New seeding status
seedingandseedRatiofield; RPC addstask.stopSeedmethod; session save/restore handles seeding tasks correctly (serialized aswaitingso they re-download on restart) - Failed dial / session addresses are re-queued for a bounded number of retries instead of waiting for the next announce
- A short-read storm exceeding 8 consecutive retries folds into one regular failure under the normal failure budget — the relaxed backoff does not slow down error reporting for permanently broken servers
- Added HTTP tail-truncation + pause/resume regression tests (short-read storms, silent stalls, cancel & resume scenarios)
- DHT hardening: known-peer table capped with FIFO eviction, inbound datagram processing concurrency limited
- Added 27 TUI rendering regression tests (border geometry, column alignment, dialog flow, detail top bar, etc.)
XferRust v0.2.0 发布说明
English | 简体中文
摘要:本版本聚焦磁力下载体验与 BT 引擎稳定性——磁力链接解析完成后以表格勾选要下载的文件(确认后才开始下载),并修复入站会话泄漏、低限速死循环与 uTP 流损坏,补齐路径穿越与元数据投毒防御,完善 ut_metadata 服务、tracker 上报与 choking 行为;同时 TUI 全面改版——新建任务弹窗支持独立下载目录(可直接调用系统目录选择框)、磁力链接输入后立即解析并向下扩展文件选择表格,主界面重构为融入背景的现代布局,任务详情页顶部保留全局信息栏。此外新增 BT 做种完整生命周期管理(可配置分享率自动停止、持续做种至手动停止)与 Android 平台引擎内核交叉编译支持;并补齐 BT 网络可发现性——本地节点发现(LPD)、UPnP/NAT-PMP 自动端口映射与 BT/DHT 监听端口可配置,修复 HTTP/HTTPS 下载收尾阶段卡在 99% 的停顿。
新功能
- 磁力链接文件选择:输入磁力链接后引擎立即解析元数据,解析完成自动暂停并弹出文件表格(勾选 + 文件大小 + 已选汇总),确认后只下载勾选的文件;跨选/未选文件边界的片按 BT 语义整体下载
- 磁力任务的会话可恢复:未确认的等待选择任务重启后重新弹出文件表格,不会跳过选择直接全量下载
- 响应 ut_metadata(BEP 9)请求:磁力 peer 按规范收到 DATA/REJECT,不再被无视
- 实现
seed_duration配置:做种到时自动正常退出并通知 tracker
BT 做种生命周期管理
- BT 任务下载完成后可配置进入做种状态(而非直接结束),通过全局选项
bt-seed-mode(true/false)控制 - 做种任务实时显示分享率(上传量 / 下载量),支持设置目标分享率
bt-seed-ratio(如1.5、2.0),达到后自动结束做种 - 做种中的任务可暂停与恢复,也可手动停止做种(RPC
task.stopSeed/ TUIS键) - 可设置持续做种直到手动停止(
bt-seed-ratio为0时不自动停止) - TUI 设置页新增做种模式与目标分享率选项,任务列表/详情页对做种状态显示上传速度与分享率
BT 网络发现与端口配置
- 本地节点发现(LPD / BEP 14):每个 BT 任务加入 LSD 组播组,周期向局域网 announce 并监听其他客户端的通告,同一内网内的节点无需 tracker 即可互相发现;发现的 peer 以
lpd来源进入调度 - UPnP / NAT-PMP 自动端口映射:BT 任务启动时自动在路由器上建立 TCP + UDP 双映射(租约 2 小时,按租期 1/3 周期续期,单次失败下个周期自动重试),任务停机时尽力撤销映射——提升可连接性,不再依赖手动在路由器开端口
- BT / DHT 监听端口可配置:新增全局选项
bt-listen-port/dht-listen-port(0= 随机端口),创建 BT 任务时生效;监听端口或 DHT 端口被占用时自动回退临时端口并记录告警,不再直接降级为不监听 - 新增开关
bt-enable-lpd/bt-port-mapping(默认均开启)可分别关闭上述两项;engine.getOptions展示新选项,changeGlobalOption校验端口取值(0–65535) - TUI 设置页同步新增四项:BT 监听端口 / DHT 监听端口(回车输入,0–65535 校验,
0显示「随机」)、本地节点发现与端口映射开关(←→ 切换);单服务器连接数、最小分片大小与界面语言顺移至其后
Android 引擎内核构建
- 新增 Android(aarch64-linux-android / arm64-v8a)交叉编译支持,仅构建引擎内核(
xferrust),不包含 TUI Cargo.toml将 TUI 依赖(crossterm、ratatui 等)改为tuifeature 下的可选依赖,default = ["tui"],xfer二进制标记required-features = ["tui"]- CI 新增
build-android作业:使用 NDK r27c + API 24(Android 7.0+)交叉编译,产物xferrust-android-arm64-v8a.tar.gz随 Release 发布 - 新增本地构建脚本
scripts/build-android.sh:自动检测 NDK host-tag(macOS / Linux),设置 CC/CXX/AR/Linker 环境变量并调用cargo build --no-default-features --bin xferrust
TUI 改版
- 新建任务弹窗重做:地址 + 目录两个字段,目录留空使用全局下载目录(仅对当前任务生效);目录可手动输入,按回车直接调用系统目录选择框选择(macOS / Windows / Linux)
- 磁力链接输入后立即解析元数据,无需二次确认,弹窗内实时显示解析进度(连接数 / 等待调度 / 已耗时);元数据就绪后任务弹窗向下扩展为文件勾选表格:空格勾选、A 全选/反选、回车确认开始下载所选文件
- 设置页的下载目录同样调用系统目录选择框选择
- 任务详情页(BT / 非 BT)顶部保留全局信息栏(品牌 logo + 全局速率/任务计数),不再切换即消失
问题修复
- 修复磁力任务下载过程中文件列表恒为空:元数据就绪后即时回填,任务详情/状态里的
files、numPieces不再显示为 0 - 修复磁力任务元数据重启后丢失:会话持久化 info 字典,恢复时按 info 解析重建,不必重新向 peer 拉取
- 修复入站 peer 会话泄漏:被动连接结束后未注销,占住的片最长停滞 180 秒
- 修复限速死循环:令牌桶容量保底一个最大块,低于 16 KiB/s 的限速不再卡死连接
- 修复 uTP 流损坏:读路径按通道容量背压,写路径缓存未接受完的字节,不再丢弃数据
- 清洗种子内路径(name / path 段),防路径穿越写到下载目录外
- 修复调度器把 0→0 吞吐当「下滑 100%」——冷启动期目标连接数不再崩塌
- 修复 choking 算法:墙钟轮次全局一致、乐观 unchoke 真正送达 lucky peer、做种上传轮转
- 修复 tracker announce 上报上传字节数恒为 0(私有 tracker 分享率可正常统计)
- 修复 UDP tracker 收不到 stopped/completed 事件
- 修复 HTTP/HTTPS 下载收尾卡在 99% 停顿十余秒:
- 尾段短读(响应体短于请求区间)改用独立退避曲线(250ms 起、1s 封顶),不再与硬错误共用 0.5–2s 退避——短读从水位续传必然推进,重试风暴下旧退避累积拖长收尾
- 新增 10 秒读空闲看门狗:连接静默停摆(对端假死 / 半开连接)时立即从水位重连续传,不再干等 30 秒读超时
- 读超时归类为可再生瞬态:不再消耗 4 次失败预算,避免尾段重试被提前判死
界面重构
- 主界面顶栏融入背景:单行显示左侧品牌 logo、右侧 ↓/↑ 全局速率与活动/等待/停止任务计数,之间以竖线分隔
- 任务区边框改为直角:上下横线左端与 logo 对齐、右端圆角与右竖线相连、四角留缺口;侧栏与内容区之间的竖线上下留空
- 侧边栏删除左上角分类标题,选中项改为背景高亮(替代指针样式)
- 任务表格:表头与数据行之间新增分隔横线(与边框同色、与列同宽、左右对称);表头与数据行左右各留 1 格间距且严格对称
- 大小列改为紧凑的「已完成 / 总大小」格式,速度列宽收窄,任务名不再把后续列顶歪
其他变更
- 新增文件选择 API:
select_files(gid, 文件索引)/get_selected_files(gid),运行中任务热生效;add_uri传bt-file-selection选项可让磁力任务解析后暂停等待选择 - 任务状态新增
awaitingSelection字段,files[].selected反映真实勾选 - 新增做种状态
seeding与seedRatio字段;RPC 新增task.stopSeed方法;会话保存/恢复正确处理做种任务(序列化为waiting以便重启后重新下载) - 拨号/会话失败的地址有限次回填重试,不再干等下一轮 announce
- 短读风暴超出连续 8 次容忍后折算为一次正常失败,由常规失败预算收敛——退避放宽不影响恒坏服务器的报错速度
- 新增 HTTP 尾部截断 + 暂停/恢复回归测试(短读风暴、静默停摆、取消续传场景)
- DHT 加固:已知 peer 表总量上限(FIFO 淘汰)、收包处理并发限制
- 新增 27 项 TUI 渲染回归测试(边框几何、列对齐、弹窗流程、详情页顶栏等)