Skip to content

Commit fd58fe0

Browse files
committed
refactored and fully support ProxyJump
1 parent af3868c commit fd58fe0

13 files changed

Lines changed: 1255 additions & 234 deletions

File tree

README.cn.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,30 @@ tssh 设计为 ssh 客户端的直接替代品,提供与 openssh 完全兼容
1515

1616
tsshd 的灵感来源于 [mosh](https://github.com/mobile-shell/mosh)`tsshd` 类似于 `mosh-server`,而 `tssh --udp` 类似于 `mosh`
1717

18-
| Feature | mosh ( mosh-server ) | tssh ( tsshd ) |
19-
| ------------------------ | :-----------------------------------------------------------: | :---------------------------------------: |
20-
| 超低延迟 | ?? |[KCP](https://github.com/xtaci/kcp-go) |
21-
| 保持连接 |||
22-
| 切换网络 |||
23-
| 本地回显 & 行编辑 || 无支持计划 |
24-
| 支持多平台 / Windows | [mosh#293](https://github.com/mobile-shell/mosh/issues/293) ||
25-
| SSH X11 转发 | [mosh#41](https://github.com/mobile-shell/mosh/issues/41) ||
26-
| SSH Agent 转发 | [mosh#120](https://github.com/mobile-shell/mosh/issues/120) ||
27-
| SSH 端口转发 | [mosh#337](https://github.com/mobile-shell/mosh/issues/337) ||
28-
| 输出上下滚动 | [mosh#122](https://github.com/mobile-shell/mosh/issues/122) ||
29-
| OSC52 复制粘贴 | [mosh#637](https://github.com/mobile-shell/mosh/issues/637) ||
30-
| tmux -CC 集成 | [mosh#1078](https://github.com/mobile-shell/mosh/issues/1078) ||
31-
| ProxyJump / ProxyCommand | [mosh#970](https://github.com/mobile-shell/mosh/issues/970) | ✅ 第一跳 |
18+
| Feature | mosh ( mosh-server ) | tssh ( tsshd ) |
19+
| -------------------- | :-----------------------------------------------------------: | :---------------------------------------: |
20+
| 超低延迟 | ?? |[KCP](https://github.com/xtaci/kcp-go) |
21+
| 保持连接 |||
22+
| 切换网络 |||
23+
| 本地回显 & 行编辑 || 无支持计划 |
24+
| 支持多平台 / Windows | [mosh#293](https://github.com/mobile-shell/mosh/issues/293) ||
25+
| SSH X11 转发 | [mosh#41](https://github.com/mobile-shell/mosh/issues/41) ||
26+
| SSH Agent 转发 | [mosh#120](https://github.com/mobile-shell/mosh/issues/120) ||
27+
| SSH 端口转发 | [mosh#337](https://github.com/mobile-shell/mosh/issues/337) ||
28+
| 输出上下滚动 | [mosh#122](https://github.com/mobile-shell/mosh/issues/122) ||
29+
| OSC52 复制粘贴 | [mosh#637](https://github.com/mobile-shell/mosh/issues/637) ||
30+
| ProxyJump | [mosh#970](https://github.com/mobile-shell/mosh/issues/970) ||
31+
| tmux -CC 集成 | [mosh#1078](https://github.com/mobile-shell/mosh/issues/1078) | |
3232

3333
tssh 和 tsshd 的工作方式与 ssh 完全相同,没有计划支持本地回显和行编辑,也不会出现 mosh 的问题:[mosh#1041](https://github.com/mobile-shell/mosh/issues/1041)[mosh#1281](https://github.com/mobile-shell/mosh/issues/1281)[mosh#1295](https://github.com/mobile-shell/mosh/issues/1295) 等。
3434

3535
## 如何使用
3636

37-
1. 在客户端(本地电脑)上安装 [tssh](https://github.com/trzsz/trzsz-ssh)
37+
1. 在客户端(本地电脑)上安装 [tssh](https://github.com/trzsz/trzsz-ssh?tab=readme-ov-file#installation)
3838

39-
2. 在服务端(远程机器)上安装 [tsshd](https://github.com/trzsz/tsshd)
39+
2. 在服务端(远程机器)上安装 [tsshd](https://github.com/trzsz/tsshd?tab=readme-ov-file#installation)
4040

41-
3. 使用 `tssh --udp` 登录服务器。在 `~/.ssh/config` 中如下配置可省略 `--udp` 参数:
41+
3. 使用 `tssh --udp xxx` 登录服务器。在 `~/.ssh/config` 中如下配置可省略 `--udp` 参数:
4242

4343
```
4444
Host xxx

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,18 @@ tsshd was inspired by [mosh](https://github.com/mobile-shell/mosh), and the `tss
2828
| SSH Port Forwarding | [mosh#337](https://github.com/mobile-shell/mosh/issues/337) ||
2929
| Output Scrollback | [mosh#122](https://github.com/mobile-shell/mosh/issues/122) ||
3030
| OSC52 Sequence | [mosh#637](https://github.com/mobile-shell/mosh/issues/637) ||
31+
| ProxyJump | [mosh#970](https://github.com/mobile-shell/mosh/issues/970) ||
3132
| tmux -CC Integration | [mosh#1078](https://github.com/mobile-shell/mosh/issues/1078) ||
32-
| ProxyJump / ProxyCommand | [mosh#970](https://github.com/mobile-shell/mosh/issues/970) | ✅ First Hop |
3333

3434
tssh and tsshd works exactly like ssh, there are no plans to support local echo and line editing, and will not have the mosh issues: [mosh#1041](https://github.com/mobile-shell/mosh/issues/1041), [mosh#1281](https://github.com/mobile-shell/mosh/issues/1281), [mosh#1295](https://github.com/mobile-shell/mosh/issues/1295), etc.
3535

3636
### How to use
3737

38-
1. Install [tssh](https://github.com/trzsz/trzsz-ssh) on the client ( the user's machine ).
38+
1. Install [tssh](https://github.com/trzsz/trzsz-ssh?tab=readme-ov-file#installation) on the client ( your local machine ).
3939

40-
2. Install [tsshd](https://github.com/trzsz/tsshd) on the server ( the remote host ).
40+
2. Install [tsshd](https://github.com/trzsz/tsshd?tab=readme-ov-file#installation) on the server ( the remote host ).
4141

42-
3. Use `tssh --udp` to login to the server. Or configure as follows in `~/.ssh/config` to omit `--udp`:
42+
3. Use `tssh --udp xxx` to login to the server. Or configure as follows in `~/.ssh/config` to omit `--udp`:
4343

4444
```
4545
Host xxx

go.mod

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,19 @@ require (
66
github.com/UserExistsError/conpty v0.1.4
77
github.com/alessio/shellescape v1.4.2
88
github.com/creack/pty v1.1.24
9-
github.com/quic-go/quic-go v0.55.0
10-
github.com/xtaci/kcp-go/v5 v5.6.24
9+
github.com/quic-go/quic-go v0.56.0
10+
github.com/xtaci/kcp-go/v5 v5.6.26
1111
github.com/xtaci/smux v1.5.35
1212
golang.org/x/crypto v0.43.0
13-
golang.org/x/sys v0.37.0
13+
golang.org/x/sys v0.38.0
1414
)
1515

1616
require (
17-
github.com/google/go-cmp v0.7.0 // indirect
17+
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
1818
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
1919
github.com/klauspost/reedsolomon v1.12.5 // indirect
2020
github.com/pkg/errors v0.9.1 // indirect
2121
github.com/tjfoc/gmsm v1.4.1 // indirect
2222
go.uber.org/mock v0.6.0 // indirect
23-
golang.org/x/mod v0.29.0 // indirect
2423
golang.org/x/net v0.46.0 // indirect
25-
golang.org/x/sync v0.17.0 // indirect
26-
golang.org/x/tools v0.38.0 // indirect
2724
)

go.sum

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
2929
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
3030
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
3131
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
32-
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
33-
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
32+
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
33+
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
3434
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
3535
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
3636
github.com/klauspost/reedsolomon v1.12.5 h1:4cJuyH926If33BeDgiZpI5OU0pE+wUHZvMSyNGqN73Y=
@@ -40,14 +40,14 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
4040
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
4141
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
4242
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
43-
github.com/quic-go/quic-go v0.55.0 h1:zccPQIqYCXDt5NmcEabyYvOnomjs8Tlwl7tISjJh9Mk=
44-
github.com/quic-go/quic-go v0.55.0/go.mod h1:DR51ilwU1uE164KuWXhinFcKWGlEjzys2l8zUl5Ss1U=
43+
github.com/quic-go/quic-go v0.56.0 h1:q/TW+OLismmXAehgFLczhCDTYB3bFmua4D9lsNBWxvY=
44+
github.com/quic-go/quic-go v0.56.0/go.mod h1:9gx5KsFQtw2oZ6GZTyh+7YEvOxWCL9WZAepnHxgAo6c=
4545
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
4646
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
4747
github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
4848
github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
49-
github.com/xtaci/kcp-go/v5 v5.6.24 h1:0tZL4NfpoESDrhaScrZfVDnYZ/3LhyVAbN/dQ2b4hbI=
50-
github.com/xtaci/kcp-go/v5 v5.6.24/go.mod h1:7cAxNX/qFGeRUmUSnnDMoOg53FbXDK9IWBXAUfh+aBA=
49+
github.com/xtaci/kcp-go/v5 v5.6.26 h1:iklAJxmvgsjUeBrzUGDbF2q7HARjbKopnFnCPXgDNRE=
50+
github.com/xtaci/kcp-go/v5 v5.6.26/go.mod h1:7cAxNX/qFGeRUmUSnnDMoOg53FbXDK9IWBXAUfh+aBA=
5151
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae h1:J0GxkO96kL4WF+AIT3M4mfUVinOCPgf2uUWYFUzN0sM=
5252
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
5353
github.com/xtaci/smux v1.5.35 h1:RosihGJBeaS8gxOZ17HNxbhONwnqQwNwusHx4+SEGhk=
@@ -63,8 +63,6 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL
6363
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
6464
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
6565
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
66-
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
67-
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
6866
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
6967
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
7068
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -77,24 +75,24 @@ golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAG
7775
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
7876
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
7977
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
80-
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
81-
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
8278
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
8379
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
8480
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
8581
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
8682
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
87-
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
88-
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
83+
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
84+
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
85+
golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q=
86+
golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss=
8987
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
9088
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
89+
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
90+
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
9191
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
9292
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
9393
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
9494
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
9595
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
96-
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
97-
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
9896
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
9997
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
10098
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=

tsshd/bus.go

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func sendBusCommand(command string) error {
4747
if stream == nil {
4848
return fmt.Errorf("bus stream is nil")
4949
}
50-
return SendCommand(*stream, command)
50+
return sendCommand(*stream, command)
5151
}
5252

5353
func sendBusMessage(command string, msg any) error {
@@ -57,29 +57,23 @@ func sendBusMessage(command string, msg any) error {
5757
if stream == nil {
5858
return fmt.Errorf("bus stream is nil")
5959
}
60-
if err := SendCommand(*stream, command); err != nil {
60+
if err := sendCommand(*stream, command); err != nil {
6161
return err
6262
}
63-
return SendMessage(*stream, msg)
63+
return sendMessage(*stream, msg)
6464
}
6565

6666
func trySendErrorMessage(format string, a ...any) {
67-
done := make(chan struct{}, 1)
68-
go func() {
69-
defer close(done)
70-
_ = sendBusMessage("error", ErrorMessage{fmt.Sprintf(format, a...)})
71-
done <- struct{}{}
72-
}()
73-
select {
74-
case <-time.After(1 * time.Second):
75-
case <-done:
76-
}
67+
_, _ = doWithTimeout(func() (int, error) {
68+
_ = sendBusMessage("error", errorMessage{fmt.Sprintf(format, a...)})
69+
return 0, nil
70+
}, 1*time.Second)
7771
}
7872

7973
func handleBusEvent(stream net.Conn) {
80-
var msg BusMessage
81-
if err := RecvMessage(stream, &msg); err != nil {
82-
SendError(stream, fmt.Errorf("recv bus message failed: %v", err))
74+
var msg busMessage
75+
if err := recvMessage(stream, &msg); err != nil {
76+
sendError(stream, fmt.Errorf("recv bus message failed: %v", err))
8377
return
8478
}
8579

@@ -88,11 +82,11 @@ func handleBusEvent(stream net.Conn) {
8882
// only one bus
8983
if !busStream.CompareAndSwap(nil, &stream) {
9084
busMutex.Unlock()
91-
SendError(stream, fmt.Errorf("bus has been initialized"))
85+
sendError(stream, fmt.Errorf("bus has been initialized"))
9286
return
9387
}
9488

95-
if err := SendSuccess(stream); err != nil { // ack ok
89+
if err := sendSuccess(stream); err != nil { // ack ok
9690
busMutex.Unlock()
9791
trySendErrorMessage("bus ack ok failed: %v", err)
9892
return
@@ -110,7 +104,7 @@ func handleBusEvent(stream net.Conn) {
110104
go keepAlive(msg.Timeout, msg.Interval)
111105

112106
for {
113-
command, err := RecvCommand(stream)
107+
command, err := recvCommand(stream)
114108
if err != nil {
115109
trySendErrorMessage("recv bus command failed: %v", err)
116110
return
@@ -136,7 +130,7 @@ func handleBusEvent(stream net.Conn) {
136130

137131
func handleUnknownEvent(stream net.Conn) error {
138132
var msg struct{}
139-
if err := RecvMessage(stream, &msg); err != nil {
133+
if err := recvMessage(stream, &msg); err != nil {
140134
return fmt.Errorf("recv unknown message failed: %v", err)
141135
}
142136
return fmt.Errorf("unknown command")

0 commit comments

Comments
 (0)