Skip to content

feat: add native Tailscale support via libts3ds#7

Open
cadl wants to merge 13 commits into
Fishason:mainfrom
cadl:codex/tailscale-3ds
Open

feat: add native Tailscale support via libts3ds#7
cadl wants to merge 13 commits into
Fishason:mainfrom
cadl:codex/tailscale-3ds

Conversation

@cadl

@cadl cadl commented Jul 11, 2026

Copy link
Copy Markdown

Important

This is a stacked PR based on #6 (cadl:codex/macos-keychain-fish-terminal). It contains the seven commits from #6 plus one Tailscale feature commit (800068f). Please review/merge #6 first; this PR can then be reviewed as the Tailscale layer on top. It should not be treated as an independent replacement for #6.

Summary

Add optional native Tailscale support to DSSH so a Nintendo 3DS can join a tailnet and open the existing SSH session through a Tailscale IPv4 address or MagicDNS name.

The transport is provided by cadl/libts3ds, an experimental native C client derived from MicroLink. It does not embed Go, run tailscaled, or claim ABI compatibility with the official tailscale/libtailscale. DSSH pins the audited source to the hardware-validated libts3ds-v0.1.0 commit through a git submodule.

What changed

  • add native Tailscale control registration, persisted node identity, WireGuard, STUN/DISCO, DERP, Tailscale Peer Relay, and private-lwIP outbound TCP through libts3ds;
  • let libssh2 use a ts3ds_conn through its send/receive callbacks while retaining native BSD sockets when Tailscale is disabled;
  • enable Tailscale when tailscale_auth_key is configured, or when a persisted state file already exists;
  • default the node name to dssh-3ds and state path to sdmc:/3ds/3dssh/tailscale.state;
  • keep the auth key in the user's configuration after registration while clearing library-owned in-memory copies;
  • support automatic direct/Peer Relay/DERP path selection, with compile-time direct, peer-relay, and derp diagnostic builds;
  • use conservative path MTUs validated on physical 3DS hardware to avoid Peer Relay TCP black holes;
  • recover lost control connections after suspend without corrupting the interactive SSH terminal;
  • keep internal transport logs quiet by default while preserving concise connection status and actionable errors;
  • document the unofficial status, state/auth-key security model, configuration, and libts3ds dependency in English and Chinese.

Build behavior

The actual build command is unchanged: after dependencies and generated assets are prepared, run make as before. The Makefile builds libts3ds/build/3ds/libts3ds.a first and then links DSSH.

The clone/setup step changes because libts3ds and its private lwIP are submodules:

git clone --recurse-submodules https://github.com/Fishason/DSSH.git
cd DSSH

For an existing non-recursive clone:

git submodule update --init --recursive

If the submodule is missing, make now prints that exact recovery command instead of failing later with a missing directory or header.

Configuration

tailscale_auth_key =
tailscale_hostname = dssh-3ds
tailscale_state = sdmc:/3ds/3dssh/tailscale.state
tailscale_control_url = https://controlplane.tailscale.com

Setting an auth key enables Tailscale. After initial registration, the persisted state also enables it without requiring the key. The state file contains machine, WireGuard, and DISCO private identity keys and must be protected like an SSH private key.

Validation

  • direct UDP, Tailscale Peer Relay, and DERP tested on physical Nintendo 3DS hardware;
  • interactive SSH, keychain bootstrap, suspend/resume, and long-running shell traffic tested on hardware;
  • bash tools/test_config.sh;
  • bash tools/test_terminal.sh;
  • bash tools/test_ime.sh;
  • make clean test in the pinned libts3ds submodule;
  • full devkitARM -Werror libts3ds build and DSSH .3dsx link;
  • fresh --recurse-submodules clone verified to fetch libts3ds-v0.1.0 and its pinned lwIP, then build successfully after the project's existing font/dictionary generation steps;
  • three-way merge check against current Fishason/DSSH:main is clean.

中文说明

本 PR 在 #6 的代码基础上增加原生 Tailscale 支持,请先审阅/合并 #6。Tailscale 部分由 cadl/libts3ds 提供,并通过 submodule 固定到真机验证过的 libts3ds-v0.1.0

构建命令仍然是原来的 make;变化仅是 clone 时需要 --recurse-submodules,已有 clone 执行 git submodule update --init --recursive。该实现可自动选择直连、Peer Relay 和 DERP,并已在 3DS 真机验证 SSH、待机恢复和长连接。它是非官方社区实现,与 Tailscale Inc. 无隶属或背书关系。

@cadl cadl force-pushed the codex/tailscale-3ds branch from 800068f to c18db6f Compare July 12, 2026 07:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant