Skip to content

v0.2.0

Choose a tag to compare

@MochengCK MochengCK released this 07 Sep 14:44
· 50 commits to main since this release

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_duration is 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 / TUI S key)
  • Continuous seeding until manual stop is supported (bt-seed-ratio of 0 disables 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 lpd source
  • 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.getOptions exposes the new options and changeGlobalOption validates port values (0–65535)
  • The TUI settings page gains the four matching rows: BT / DHT listen port (Enter to edit, validated 0–65535, 0 shown 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.toml makes TUI dependencies (crossterm, ratatui, etc.) optional under a tui feature; default = ["tui"]; the xfer binary is marked required-features = ["tui"]
  • CI adds a build-android job: cross-compiles with NDK r27c + API 24 (Android 7.0+); artifact xferrust-android-arm64-v8a.tar.gz is 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 invokes cargo 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 files and numPieces are 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_uri accepts a bt-file-selection option to pause a magnet task after parsing and wait for a selection
  • Task status exposes a new awaitingSelection field, and files[].selected now reflects the real selection
  • New seeding status seeding and seedRatio field; RPC adds task.stopSeed method; session save/restore handles seeding tasks correctly (serialized as waiting so 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-modetrue/false)控制
  • 做种任务实时显示分享率(上传量 / 下载量),支持设置目标分享率 bt-seed-ratio(如 1.52.0),达到后自动结束做种
  • 做种中的任务可暂停与恢复,也可手动停止做种(RPC task.stopSeed / TUI S 键)
  • 可设置持续做种直到手动停止(bt-seed-ratio0 时不自动停止)
  • 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-port0 = 随机端口),创建 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 等)改为 tui feature 下的可选依赖,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 + 全局速率/任务计数),不再切换即消失

问题修复

  • 修复磁力任务下载过程中文件列表恒为空:元数据就绪后即时回填,任务详情/状态里的 filesnumPieces 不再显示为 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_uribt-file-selection 选项可让磁力任务解析后暂停等待选择
  • 任务状态新增 awaitingSelection 字段,files[].selected 反映真实勾选
  • 新增做种状态 seedingseedRatio 字段;RPC 新增 task.stopSeed 方法;会话保存/恢复正确处理做种任务(序列化为 waiting 以便重启后重新下载)
  • 拨号/会话失败的地址有限次回填重试,不再干等下一轮 announce
  • 短读风暴超出连续 8 次容忍后折算为一次正常失败,由常规失败预算收敛——退避放宽不影响恒坏服务器的报错速度
  • 新增 HTTP 尾部截断 + 暂停/恢复回归测试(短读风暴、静默停摆、取消续传场景)
  • DHT 加固:已知 peer 表总量上限(FIFO 淘汰)、收包处理并发限制
  • 新增 27 项 TUI 渲染回归测试(边框几何、列对齐、弹窗流程、详情页顶栏等)