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,50 @@
import Foundation
/// `mosh-server new` `MOSH CONNECT <port> <key>`
///
/// SSH `mosh-server new ` detach stdout
/// UDP + key host:port SSH /
/// `feed`
public struct MoshConnectInfo: Equatable, Sendable {
public let port: Int
public let key: String
public init(port: Int, key: String) { self.port = port; self.key = key }
}
public final class MoshConnectScanner {
private var buffer = ""
private var found: MoshConnectInfo?
public init() {}
///
@discardableResult
public func feed(_ text: String) -> MoshConnectInfo? {
if let found { return found }
buffer += text
// 8KB feed
if buffer.count > 8192 { buffer = String(buffer.suffix(8192)) }
if let info = Self.parse(buffer) { found = info; return info }
return nil
}
public var result: MoshConnectInfo? { found }
/// `MOSH CONNECT <port> <key>`key base64AES-128
public static func parse(_ text: String) -> MoshConnectInfo? {
guard let range = text.range(of: "MOSH CONNECT ") else { return nil }
let rest = text[range.upperBound...]
// token port key
// Swift "\r\n" Character $0 != "\r"
// isNewline \n / \r / \r\n
let line = rest.split(whereSeparator: { $0.isNewline }).first ?? ""
let parts = line.split(whereSeparator: { $0 == " " || $0 == "\t" })
guard parts.count >= 2, let port = Int(parts[0]) else { return nil }
let key = String(parts[1])
// key base64 key
guard !key.isEmpty, key.allSatisfy({ $0.isLetter || $0.isNumber || $0 == "+" || $0 == "/" || $0 == "=" }) else {
return nil
}
return MoshConnectInfo(port: port, key: key)
}
}