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)
}
}

View File

@@ -0,0 +1,37 @@
import XCTest
@testable import TXCore
final class MoshConnectTests: XCTestCase {
func testParseBasic() {
let info = MoshConnectScanner.parse("MOSH CONNECT 60001 gPFm3s8bkfMGrun5QI0Xdw")
XCTAssertEqual(info, MoshConnectInfo(port: 60001, key: "gPFm3s8bkfMGrun5QI0Xdw"))
}
func testParseAmidNoise() {
let out = """
user@host:~$ mosh-server new -s -c 256\r
\r
MOSH CONNECT 60022 AbCd1234+/xyzKEY0000==\r
\r
mosh-server (mosh 1.4.0)\r
"""
let info = MoshConnectScanner.parse(out)
XCTAssertEqual(info?.port, 60022)
XCTAssertEqual(info?.key, "AbCd1234+/xyzKEY0000==")
}
func testNoMatch() {
XCTAssertNil(MoshConnectScanner.parse("bash: mosh-server: command not found"))
XCTAssertNil(MoshConnectScanner.parse("MOSH CONNECT notaport keyhere"))
}
func testStreamingAcrossFeeds() {
let s = MoshConnectScanner()
XCTAssertNil(s.feed("prompt$ mosh-server new\r\nMOSH CON"))
XCTAssertNil(s.result)
let info = s.feed("NECT 60007 KeyAcrossBoundary123\r\n")
XCTAssertEqual(info, MoshConnectInfo(port: 60007, key: "KeyAcrossBoundary123"))
// feed
XCTAssertEqual(s.feed("MOSH CONNECT 61000 other"), MoshConnectInfo(port: 60007, key: "KeyAcrossBoundary123"))
}
}