feat: 完成 M2 mosh(LAN + tsnet 端到端验证)

- mosh(blinksh/ios C++)+protobuf-lite 交叉编译为 MoshCore.xcframework
  (CommonCrypto 后端、含 arm64 模拟器 slice;绕 autotools 用 CMake 直编 + 手写 config.h)
- tsnet 桥新增 UDP relay(StartMoshRelay:loopback↔tsnet.Dial 逐包搬运)
- MoshSession(pipe↔FILE*/pthread/SIGWINCH)+ MoshConnectScanner(TXCore,+4 单测=39)
- SSHTerminalModel 编排:SSH 引导 mosh-server→解析 MOSH CONNECT→relay→mosh 接管
- LAN 直连 + mosh-over-tsnet 均端到端验证通过,R1(tsnet UDP 数据报语义) 证伪

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
kid
2026-07-24 16:14:40 +08:00
parent aa92d0e676
commit 32520f09e0
1232 changed files with 728138 additions and 37 deletions

View File

@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AvailableLibraries</key>
<array>
<dict>
<key>BinaryPath</key>
<string>libMoshCore.a</string>
<key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string>
<key>LibraryPath</key>
<string>libMoshCore.a</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
<dict>
<key>BinaryPath</key>
<string>libMoshCore.a</string>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<key>LibraryPath</key>
<string>libMoshCore.a</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
</dict>
<dict>
<key>BinaryPath</key>
<string>libMoshCore.a</string>
<key>LibraryIdentifier</key>
<string>macos-arm64</string>
<key>LibraryPath</key>
<string>libMoshCore.a</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>macos</string>
</dict>
</array>
<key>CFBundlePackageType</key>
<string>XFWK</string>
<key>XCFrameworkFormatVersion</key>
<string>1.0</string>
</dict>
</plist>

Binary file not shown.

View File

@@ -4,20 +4,6 @@
<dict>
<key>AvailableLibraries</key>
<array>
<dict>
<key>BinaryPath</key>
<string>TsnetBridge.framework/TsnetBridge</string>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<key>LibraryPath</key>
<string>TsnetBridge.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
</dict>
<dict>
<key>BinaryPath</key>
<string>TsnetBridge.framework/TsnetBridge</string>
@@ -35,6 +21,20 @@
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
<dict>
<key>BinaryPath</key>
<string>TsnetBridge.framework/TsnetBridge</string>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<key>LibraryPath</key>
<string>TsnetBridge.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
</dict>
</array>
<key>CFBundlePackageType</key>
<string>XFWK</string>

View File

@@ -11,8 +11,31 @@
#include "Universe.objc.h"
@class TsnetbridgeMoshRelay;
@class TsnetbridgeNode;
/**
* MoshRelay 是一条 mosh-over-tsnet 的 UDP 中继:
mosh-client 在本地把 UDP 包发到 127.0.0.1:<LocalPort>,本中继逐包经 tsnet 转发到
tailnet 内 host:moshPort回包再转回"最近一次上行的 client 源地址"(吸收 mosh 的 roaming/端口跳变)。
与 DialTCPFD 的差异mosh 内部自建 UDP socket 并 connect(),无法注入外部 fd故用 loopback relay。
*/
@interface TsnetbridgeMoshRelay : NSObject <goSeqRefInterface> {
}
@property(strong, readonly) _Nonnull id _ref;
- (nonnull instancetype)initWithRef:(_Nonnull id)ref;
- (nonnull instancetype)init;
/**
* Close 关闭中继(两条泵 goroutine 随即因 conn 关闭而退出)。
*/
- (BOOL)close:(NSError* _Nullable* _Nullable)error;
/**
* LocalPort 返回 loopback relay 监听的端口mosh_main 的 port 参数)。
*/
- (long)localPort;
@end
/**
* Node 包装一个嵌入式 tsnet 节点。gomobile 导出为引用型对象。
*/
@@ -44,6 +67,11 @@ Swift 侧 close(fd) 会触发泵结束并关闭 tsConn。返回 -1 + error 表
* SelfIP 返回本节点的 Tailscale IPv4经 LocalClient().Status() 取;未就绪返回空串)。
*/
- (NSString* _Nonnull)selfIP;
/**
* StartMoshRelay 建立中继并启动双向泵返回句柄。Swift 用 LocalPort() 作为 mosh_main 的 port
参数、ip 传 "127.0.0.1"。失败返回 nil + error。timeoutMs 限制 tsnet UDP Dial 的建连等待。
*/
- (TsnetbridgeMoshRelay* _Nullable)startMoshRelay:(NSString* _Nullable)host moshPort:(long)moshPort timeoutMs:(long)timeoutMs error:(NSError* _Nullable* _Nullable)error;
/**
* UpWithAuthKey 用 auth key 启动并等待 RunningtimeoutMs 到则返回 error
gomobile 友好签名基本类型入参、error 出参。

View File

@@ -9,9 +9,9 @@
<key>MinimumOSVersion</key>
<string>100.0</string>
<key>CFBundleShortVersionString</key>
<string>0.0.1784856790</string>
<string>0.0.1784861278</string>
<key>CFBundleVersion</key>
<string>0.0.1784856790</string>
<string>0.0.1784861278</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
</dict>

View File

@@ -11,8 +11,31 @@
#include "Universe.objc.h"
@class TsnetbridgeMoshRelay;
@class TsnetbridgeNode;
/**
* MoshRelay 是一条 mosh-over-tsnet 的 UDP 中继:
mosh-client 在本地把 UDP 包发到 127.0.0.1:<LocalPort>,本中继逐包经 tsnet 转发到
tailnet 内 host:moshPort回包再转回"最近一次上行的 client 源地址"(吸收 mosh 的 roaming/端口跳变)。
与 DialTCPFD 的差异mosh 内部自建 UDP socket 并 connect(),无法注入外部 fd故用 loopback relay。
*/
@interface TsnetbridgeMoshRelay : NSObject <goSeqRefInterface> {
}
@property(strong, readonly) _Nonnull id _ref;
- (nonnull instancetype)initWithRef:(_Nonnull id)ref;
- (nonnull instancetype)init;
/**
* Close 关闭中继(两条泵 goroutine 随即因 conn 关闭而退出)。
*/
- (BOOL)close:(NSError* _Nullable* _Nullable)error;
/**
* LocalPort 返回 loopback relay 监听的端口mosh_main 的 port 参数)。
*/
- (long)localPort;
@end
/**
* Node 包装一个嵌入式 tsnet 节点。gomobile 导出为引用型对象。
*/
@@ -44,6 +67,11 @@ Swift 侧 close(fd) 会触发泵结束并关闭 tsConn。返回 -1 + error 表
* SelfIP 返回本节点的 Tailscale IPv4经 LocalClient().Status() 取;未就绪返回空串)。
*/
- (NSString* _Nonnull)selfIP;
/**
* StartMoshRelay 建立中继并启动双向泵返回句柄。Swift 用 LocalPort() 作为 mosh_main 的 port
参数、ip 传 "127.0.0.1"。失败返回 nil + error。timeoutMs 限制 tsnet UDP Dial 的建连等待。
*/
- (TsnetbridgeMoshRelay* _Nullable)startMoshRelay:(NSString* _Nullable)host moshPort:(long)moshPort timeoutMs:(long)timeoutMs error:(NSError* _Nullable* _Nullable)error;
/**
* UpWithAuthKey 用 auth key 启动并等待 RunningtimeoutMs 到则返回 error
gomobile 友好签名基本类型入参、error 出参。

View File

@@ -9,9 +9,9 @@
<key>MinimumOSVersion</key>
<string>100.0</string>
<key>CFBundleShortVersionString</key>
<string>0.0.1784856790</string>
<string>0.0.1784861278</string>
<key>CFBundleVersion</key>
<string>0.0.1784856790</string>
<string>0.0.1784861278</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
</dict>