相片尾图
分级浏览器客户端, ts连接( Go编译为 js/wasm),带有APIs 系统 需要使用尾网作为网络传输. 发表于 @ai-ecoverse/wasm-tailscale。 。 。 .
此 repo 没有 Tailscale 源代码 。 把它钉入了尾图标记 upstream.json ,并将 SLICC 的更改作为可读补丁序列保存在 patches/。 。 。 . build.sh 复制标签,检查承诺,应用补丁并构建 package/dist/。 。 。 .
补丁添加的
在上游Tsconnect的顶端 run, (中文(简体) ), login, (中文(简体) ), logout, (中文(简体) ), ssh 财务报告和审定财务报表 fetch(url)数字 :
-
fetch(request)数字 : 一个完整的HTTP请求(方法,标题,正文)通过尾网,并有流化响应(read()编号 :cancel()) (中文(简体) ). 逐一列出的头条websocket下文和Content-Length从请求中删除; 主机设置请求的主机 .manualRedirects返回未跟踪的重定向。 与encodedBodies关闭,去谈判gzip 解码身体。 TLS是Go自己的,与Mozilla的根证书进行校验,由于Go没有系统根根,所以Go的根证书被嵌入其中js/wasm不适用CORS. -
dial(network, addr)数字 : 原始 TCP( 或 UDP) 连接read(), (中文(简体) ),write(), (中文(简体) ),closeWrite()(单位:千美元)shutdown(SHUT_WR)和close()。之后不要使用连接close():它的功能大约在一秒后被放出,然后调用一个然后扔出"调用所放出的职能". 每个拨号在30秒后就放弃了. -
websocket({ url, protocols, headers, signal })数字 : a 在尾网上的WebSocket,在同一个拨号器上与fetch财务报告和审定财务报表dial:一个公共主机通过出站节点,一个尾网名称或地址到对等点. 是吴的"WebSocket"编码器/网格"去"执行,上游建设仅外出js/wasm,所以补上0015份tempfork/coder/websocket),从不浏览器的:握手会穿过内网,所以没有浏览器饼干,Origin或CORS 永远适用.wss:对照捆绑的根进行核查,因为fetch没错 它能解决内核形状的物体RealmWebSocket数字 :protocol: 服务器选择的子议定书, 或""· ;buffered: 给定的字节send尚未写成;send(string | Uint8Array | ArrayBuffer): 队列文本或二进制消息。 返回一个Error而不是投掷 :code: 'EPIPE'一旦套接字关闭,code: 'EMSGSIZE'用于超过64个 MiB 的信息,它也用 1009 关闭了套接字 。 一个字符串在复制到Go之前被测量,所以一个超大小的成本 没有记忆;messages: a 同步可移动( )for await),或打电话messages.next()页:1{ value, done }。每个值是一个整条消息(碎片重新组装):用于文本的字符串, aUint8Array二进制.return()放下剩下的东西 超过64个的MiB收到消息,以1009关闭了套接字. 小平在"去"中被回答,从不露出. 最多16个MiB信件等待next()不仅如此 Go停止了阅读 同行也感受到TCP的后压;close(code, reason):在什么之后发送一个近距离帧send已排队 。 一个客户端无法发送的代码会变为1000;其原因是在一个UTF-8边界被切到123字节. 与浏览器的 CLOSING 状态一样, 端点在它自己的近距离前发送信件messages;对等点有5 s来发送这个帧,或者连接被撕毁;closed承诺{ code, reason },从对等方的相近框架, 无论它开始关闭还是回答我们的, 1005 对于一个没有代码的框架, 1006 对于一个没有代码的连接.
headers(单位:千美元)[name, value][]进入握手,但东道主除外,Sec-WebSocket-*, Cookie, Content-Length 和 hop-by- hop 标题: 连接和它命名的页眉, Keep-Alive, Proxy- Authorization, Proxy- Authenticate, Proxy- Connection, TE, Trailer, Transfer-Encoding and Uplairation (握手设置自己的连接和升级). 拒绝握手拒绝Error谁status是 HTTP 状态( 403 等); 重定向没有被遵循, 就像浏览器一样 .signal(单位:千美元)AbortSignal)取消握手,拒绝与signal.reason,然后用 1001 关闭打开的套接字 :send队列被丢弃, 并取消正在写入, 将连接撕下( 然后closed给予1006),因为一个停止阅读的对等点,否则可以永远地保持收尾. 一次closed已经解决messages对象的功能已经终结, 成为普通JS的站立 和Go's的 发布一秒钟后, 所以不要一直提到他们过去。 一个封闭的套接字为一个仍然忙于阅读的读者保留其未读消息,除了三个例外,它会丢掉它们,并以同样的方式发布:signal中止(所有者已离去),关闭时持有超过16个米B,或messages没有next()关闭5分钟后。 被丢弃的消息从来不是静态的结束 :next()然后拒绝,与signal.reason流产后,或者Error谁code实值'EDROPPED'以及他们dropped是丢失信件的数量.messages.return()故意丢掉,说好了. -
setExitNode(expr)数字 :""没有,auto:any,一个IP,一个MagicDNS名称或稳定的节点ID. 名称或ID由节点地址选择,因为ExitNodeID设置通过EditPrefs头等舱空空而回. -
status()数字 : 后端状态,这个节点,它的对等点,出口节点,shieldsUp财务报告和审定财务报表controlURL作为JSON。 可以从notify*调用,补丁完成他们自己的联署任务。 上游称它们从内部同步出击 Go, 在那里召回 Go 僵局 js/wasm的单线. 这个stateStorage回调必须保持同步,因为Go需要getState答曰. 师曰. 在他们体内,status()返回一个Error而不是绞死。 把它拖过去setTimeout(…, 0)。投出回调不会结束 Go 程序 :- 掷出
notify*通过调用报告notifyPanicRecover,而节点持续运行; - 掷出
stateStorage回调成为了Go内部的存储错误. 以下内容取决于何时发生:- 时
newIPN构建后端,newIPN返回一个Error(单位:千美元)newIPN: <step>: …(a) 而不是节点; - 期间
run()开始时,节点会停止NoState,以及notifyPanicRecover报告Tailscale could not start: …。稍后时间login()或者说login(key)再次运行启动:一旦存储工作完成,它就会到达NeedsLogin如果它仍然失败,它将再次报告失败; - 后来,Tailscale处理它就像任何失败的状态写入:更改没有被保存,节点持续运行.
- 时
- 掷出
-
login(authKey)数字 : 登录启动后到达的认证密钥, 例如用户粘贴的密钥 。 密钥只是开始的选项;它从未被存储. 两者login()财务报告和审定财务报表login(authKey)之前被拒绝run(),并等待run()开始了 登录和logout()一次运行一次,这样一来,它们就破裂了(如每页记录一次)NeedsLogin而用户粘贴一个密钥)无法满足两个控制客户端之间的后端. -
配置 :
newIPN带exitNode, (中文(简体) ),ephemeral(默认)true,作为上游)和logUpload(默认)false,所以没有去log.tailscale.com) (中文(简体) ). 一个空的controlURL指Tailscale的默认控制服务器. -
护盾, 保持: 尾网对等点无法打开连接到节点.
run()开始设置屏蔽, 配置的控制服务器, 主机名和接受的路由 。 在每次登录(有或没有密钥)之前、之后再次应用同样的预览logout()(它用 Tailscale 的默认来取代配置文件: 屏蔽下,默认的控制服务器),并且当一个预览更改时会丢掉其中的任何一个. 登录等待到run()'开始已返回. -
子网线路接受 (单位:千美元)
RouteAll与上游的tsconnection不同。 使用其他节点广告的路线,其流量流向广告端,而不是出站节点. -
构建特性 : 构造保存
useexitnode, (中文(简体) ),peerapiclient(DNS通过出站节点)和useroutes。所有为同伴服务的东西( peerapi 服务器、 服务、 ssh 服务器、 尾滴、 驱动器) 都保持编译, 如在 上游 构建 .
包裹
dist/main.wasm:约30 MB,4.7 MB与brotli.dist/wasm_exec.js:从同名Go工具链.dist/build-info.json: Tailscale 标记和承诺,Go版本,每个补丁和文件的sha256.THIRD-PARTY-NOTICES.md: 与main.wasm(见下文).index.d.ts:上方的API.
装上它,快跑 wasm_exec.js (定义 globalThis.Go),即时 main.wasm 与 new Go().importObject电话 go.run(instance),并等待 globalThis.newIPN。 。 。 . newIPN 每个 JavaScript 域是一个单一的全球, 所以运行在自己的工人.
stateStorage 拥有秘密. 模块保存 _machinekey, (中文(简体) ), log-policy 和档案状态。 与 ephemeral: false,包括节点的私人密钥,所以谁持有存储器都可以充当节点. 嵌入器必须像证书一样存储: 不是在 localStorage 在共享来源,而不是在日志中。 认证密钥从未写入 stateStorage。 。 。 .
THIRD-PARTY-NOTICES.md 列表中 将模块链接到 main.wasm及其许可 版权和NOTICE文件 加上Go标准图书馆的许可. build.sh 从 go list -deps 和大楼的标签.
版本为 <tailscale version>-<n>,例如 1.104.1-1· ; n 计算同一标签的释放量.
构建
./build.sh # clones into .build/tailscale, or set TAILSCALE_SRC
npm test # builds, then runs every test below but logout-check
node test/release.mjs # the next build number and the release's tarball check
node test/smoke.mjs # reaches Tailscale's control plane, checks shields up and the API
node test/empty-control-url.mjs # an empty controlURL settles on the default
node test/throwing-callbacks.mjs # throwing callbacks are survived and reported
node test/storage-failure.mjs newipn # broken storage: newIPN returns an Error
node test/storage-failure.mjs start # broken storage during run(): reported, login() retries, works once storage recovers
node test/login-bursts.mjs healthy # l,k,l and l,l,k,l login bursts survive
node test/login-bursts.mjs failed-start # the same after a failed start, then a URL once storage recovers
scripts/local-tailnet.sh # a tailnet of its own: join, dial a peer, half-close, WebSockets to the peer by address and name, nothing inbound, exit node by name and ID
node test/logout-check.mjs # interactive: join, logout, login again; prints sign-in links to /tmp/logout-check.out
scripts/local-tailnet.sh 被绑定的下载, sha256 检查的头级 0.29.4 和 Tailscale 1.104.1 (Linux x86 64) 输入临时目录, 或使用 HEADSCALE, (中文(简体) ), TAILSCALED 财务报告和审定财务报表 TAILSCALE 当这三种人被集合而运行的时候 test/local-tailnet.mjs。 。 。 .
该建筑使用Tailscale被钉住的Go工具链(./tool/go, (中文(简体) ), -trimpath, (中文(简体) ), -buildvcs=false 和一个空的构建 ID, 所以相同的标签、 补丁和版本给出相同的 main.wasm 在任何机器上。 版本被烤入,所以一个建筑 外一个发行说 0.0.0-dev。 。 。 .
更新
要移动到一个新的 Tailscale 标记, 将补丁系列重新定位到它上 。 在分级克隆中,应用 patches/*.patch 到旧标签 git am,然后刷新 patches/ 与 git format-patch <new-tag>..HEAD更新 upstream.json缩放版本 scripts/local-tailnet.sh 下载。 新标签的首次发布是 <new version>-1。 。 。 .
中情局
ci.yml 运行 塑料-共享网络管道 在合并队列中和在 main。 。 。 . npm run lint 运行外壳检查和检查 patches/ 适用于被贴标签; npm test 以一项工作建立和运行上面的测试;在拉动请求下,克洛德和克多克思审查修改.
每一次推动 main 带有 fix, (中文(简体) ), feat 或者说 perf 自上次释放以来,通过语义释放(.releaserc.json) (中文(简体) ). scripts/release.mjs 选择版本, 一次通过最高 n npm 有标记在 upstream.json,构建 package/ 带着它,用这个读取器和LICENSE来包装它。 它拒绝一个柏油球 它的文件不是这个建筑所写的 build-info.json 由建筑物自己的文件),从另一个承诺或版本所建,或者在外部保存链接或条目 package/它出版的有 npm 信任的出版(OIDC)和出处的柏油球,下 latest,则GitHub 发布名称。 语义解说-释放在 release-X.Y.Z git 标记, 它只标记已发布的内容 .
许可证
BSD 3- Clause, 作为 Tailscale (参见 自由主义) (中文(简体) ). 补丁同被发证. main.wasm 也包含Apache-2.0、MIT和BSD许可下的代码;参见 THIRD-PARTY-NOTICES.md 在包裹.