Merge pull request #39 from lwch/dev

v0.10.0
This commit is contained in:
李文超
2022-07-28 15:58:17 +08:00
committed by GitHub
67 changed files with 2797 additions and 273 deletions
+1
View File
@@ -47,5 +47,6 @@ jobs:
run: |
go run contrib/bindata/main.go -pkg shell -o code/client/rule/shell/assets.go -prefix html/shell html/shell/...
go run contrib/bindata/main.go -pkg vnc -o code/client/rule/vnc/assets.go -prefix html/vnc html/vnc/...
go run contrib/bindata/main.go -pkg code -o code/client/rule/code/assets.go -prefix html/code html/code/...
go run contrib/bindata/main.go -pkg dashboard -o code/client/dashboard/assets.go -prefix html/dashboard html/dashboard/...
go build -v code/client/main.go
+2 -2
View File
@@ -1,8 +1,8 @@
/bin
/test
/build
/release
/tmp
/logs
/run
/*.yaml
/*.yaml
/test_conf
+7 -1
View File
@@ -127,4 +127,10 @@
# v0.9.1
1. 修正客户端在断网后会假死的问题
1. 修正客户端在断网后会假死的问题
# v0.10.0
1. go版本升级到1.18.4
2. 新增code-server支持
3. 优化disconnect处理逻辑
+19 -31
View File
@@ -41,46 +41,34 @@ dashboard页面
![dashboard](docs/imgs/dashboard.png)
linux命令行效果
命令行
![linux-shell](docs/imgs/shell_linux.png)
| platform | 386 | amd64 | arm | arm64 |
| -------- | :-: | :---: | :-: | :---: |
| windows | ✅ | ✅ | ✅ | ✅ |
| macos | | ✅ | | ✅ |
| linux | ✅ | ✅ | ✅ | ✅ |
windows命令行效果
![shell](docs/imgs/shell.gif)
![windows-shell](docs/imgs/shell_win.png)
远程桌面
windows2008远程桌面
| platform | 386 | amd64 | arm | arm64 |
| -------- | :-: | :---: | :-: | :---: |
| windows | ✅ | ✅ | ❌ | ❌ |
| macos | | ✅ | | ✅ |
| linux | ✅ | ✅ | ❌ | ❌ |
![win2008-vnc](docs/imgs/vnc_win2008.png)
![vnc](docs/imgs/vnc.gif)
windows10远程桌面
![win10-vnc](docs/imgs/vnc_win10.png)
windows11远程桌面
![win11-vnc](docs/imgs/vnc_win11.png)
ubuntu远程桌面
![ubuntu-vnc](docs/imgs/vnc_ubuntu.png)
fedora远程桌面
![fedora-vnc](docs/imgs/vnc_fedora.png)
deepin远程桌面
![deepin-vnc](docs/imgs/vnc_deepin.png)
macos远程桌面
![macos-vnc](docs/imgs/vnc_macos.png)
windows读取剪贴板内容
windows剪贴板内容
![vnc-clipboard](docs/imgs/vnc_clipboard.png)
code-server支持
![code-server](docs/imgs/code_server.png)
## 性能
在vmware环境下创建4C2GAMD Ryzen 7 4800U with Radeon Graphics)测试环境,并进行all in one部署server、remote端和local端,使用bench规则进行压测,结果如下:
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/sh
VERSION=0.9.1
VERSION=0.10.0
DOCKER_BUILDKIT=1 docker build -t natpass -f contrib/build/Dockerfile .
docker run --rm \
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/sh
VERSION=0.9.1
VERSION=0.10.0
DOCKER_BUILDKIT=1 docker build -t natpass -f contrib/build/Dockerfile .
docker run --rm \
+15
View File
@@ -11,6 +11,7 @@ import (
"github.com/lwch/natpass/code/client/global"
"github.com/lwch/natpass/code/client/rule"
"github.com/lwch/natpass/code/client/rule/bench"
"github.com/lwch/natpass/code/client/rule/code"
"github.com/lwch/natpass/code/client/rule/shell"
"github.com/lwch/natpass/code/client/rule/vnc"
"github.com/lwch/natpass/code/network"
@@ -77,6 +78,10 @@ func (a *App) run() {
b := bench.New(t)
mgr.Add(b)
go b.Handle(a.conn)
case "code-server":
cs := code.New(t, a.cfg.ReadTimeout, a.cfg.WriteTimeout)
mgr.Add(cs)
go cs.Handle(a.conn)
}
}
@@ -93,11 +98,14 @@ func (a *App) run() {
a.vncCreate(a.confDir, mgr, a.conn, msg)
case network.ConnectRequest_bench:
a.benchCreate(a.confDir, mgr, a.conn, msg)
case network.ConnectRequest_code:
a.codeCreate(a.confDir, mgr, a.conn, msg)
}
default:
linkID = msg.GetLinkId()
}
if len(linkID) > 0 {
a.conn.ChanClose(linkID)
logging.Error("link of %s not found, type=%s",
linkID, msg.GetXType().String())
continue
@@ -105,6 +113,13 @@ func (a *App) run() {
}
}()
go func() {
for {
id := <-a.conn.ChanDisconnect()
mgr.OnDisconnect(id)
}
}()
if a.cfg.DashboardEnabled {
go func() {
a.conn.Wait()
+30 -4
View File
@@ -5,6 +5,7 @@ import (
"github.com/lwch/natpass/code/client/conn"
"github.com/lwch/natpass/code/client/global"
"github.com/lwch/natpass/code/client/rule"
"github.com/lwch/natpass/code/client/rule/code"
"github.com/lwch/natpass/code/client/rule/shell"
"github.com/lwch/natpass/code/client/rule/vnc"
"github.com/lwch/natpass/code/network"
@@ -12,7 +13,7 @@ import (
func (a *App) shellCreate(mgr *rule.Mgr, conn *conn.Conn, msg *network.Msg) {
create := msg.GetCreq()
tn := mgr.Get(create.GetName(), msg.GetFrom())
tn := mgr.GetLinked(create.GetName(), msg.GetFrom())
if tn == nil {
tn = shell.New(global.Rule{
Name: create.GetName(),
@@ -21,7 +22,7 @@ func (a *App) shellCreate(mgr *rule.Mgr, conn *conn.Conn, msg *network.Msg) {
Exec: create.GetCshell().GetExec(),
Env: create.GetCshell().GetEnv(),
}, a.cfg.ReadTimeout, a.cfg.WriteTimeout)
mgr.Add(tn)
mgr.Add(tn.(rule.Rule))
}
lk := tn.NewLink(msg.GetLinkId(), msg.GetFrom(), nil, conn).(*shell.Link)
logging.Info("create link %s for shell rule [%s] from %s to %s",
@@ -39,7 +40,7 @@ func (a *App) shellCreate(mgr *rule.Mgr, conn *conn.Conn, msg *network.Msg) {
func (a *App) vncCreate(confDir string, mgr *rule.Mgr, conn *conn.Conn, msg *network.Msg) {
create := msg.GetCreq()
tn := mgr.Get(create.GetName(), msg.GetFrom())
tn := mgr.GetLinked(create.GetName(), msg.GetFrom())
if tn == nil {
tn = vnc.New(global.Rule{
Name: create.GetName(),
@@ -47,7 +48,7 @@ func (a *App) vncCreate(confDir string, mgr *rule.Mgr, conn *conn.Conn, msg *net
Type: "vnc",
Fps: create.GetCvnc().GetFps(),
}, a.cfg.ReadTimeout, a.cfg.WriteTimeout)
mgr.Add(tn)
mgr.Add(tn.(rule.Rule))
}
lk := tn.NewLink(msg.GetLinkId(), msg.GetFrom(), nil, conn).(*vnc.Link)
logging.Info("create link %s for vnc rule [%s] from %s to %s",
@@ -71,3 +72,28 @@ func (a *App) benchCreate(confDir string, mgr *rule.Mgr, conn *conn.Conn, msg *n
msg.GetFrom(), a.cfg.ID)
conn.SendConnectOK(msg.GetFrom(), msg.GetLinkId())
}
func (a *App) codeCreate(confDir string, mgr *rule.Mgr, conn *conn.Conn, msg *network.Msg) {
create := msg.GetCreq()
tn := mgr.GetLinked(create.GetName(), msg.GetFrom())
if tn == nil {
tn = code.New(global.Rule{
Name: create.GetName(),
Target: msg.GetFrom(),
Type: "code-server",
}, a.cfg.ReadTimeout, a.cfg.WriteTimeout)
mgr.Add(tn.(rule.Rule))
}
workspace := tn.NewLink(msg.GetLinkId(), msg.GetFrom(), nil, conn).(*code.Workspace)
logging.Info("create link %s for code-server rule [%s] from %s to %s",
msg.GetLinkId(), create.GetName(),
msg.GetFrom(), a.cfg.ID)
err := workspace.Exec(a.cfg.CodeDir)
if err != nil {
logging.Error("create vnc failed: %v", err)
conn.SendConnectError(msg.GetFrom(), msg.GetLinkId(), err.Error())
return
}
conn.SendConnectOK(msg.GetFrom(), msg.GetLinkId())
workspace.Forward()
}
+103 -40
View File
@@ -3,6 +3,7 @@ package conn
import (
"context"
"crypto/tls"
"io"
"net"
"strings"
"sync"
@@ -15,16 +16,19 @@ import (
"github.com/lwch/runtime"
)
const dropBlockTimeout = 10 * time.Minute
// Conn connection
type Conn struct {
sync.RWMutex
cfg *global.Configure
conn *network.Conn
read map[string]chan *network.Msg // link id => channel
unknownRead chan *network.Msg // read message without link
write chan *network.Msg
lockDrop sync.RWMutex
drop map[string]time.Time
cfg *global.Configure
conn *network.Conn
read map[string]chan *network.Msg // link id => channel
unknownRead chan *network.Msg // read message without link
onDisconnect chan string
write chan *network.Msg
lockDrop sync.RWMutex
drop map[string]time.Time
// runtime
ctx context.Context
cancel context.CancelFunc
@@ -33,11 +37,12 @@ type Conn struct {
// New new connection
func New(cfg *global.Configure) *Conn {
conn := &Conn{
cfg: cfg,
read: make(map[string]chan *network.Msg),
unknownRead: make(chan *network.Msg, 1024),
write: make(chan *network.Msg, 1024),
drop: make(map[string]time.Time),
cfg: cfg,
read: make(map[string]chan *network.Msg),
unknownRead: make(chan *network.Msg, 1024),
onDisconnect: make(chan string, 1024),
write: make(chan *network.Msg, 10*1024*1024),
drop: make(map[string]time.Time),
}
runtime.Assert(conn.connect())
conn.ctx, conn.cancel = context.WithCancel(context.Background())
@@ -90,11 +95,68 @@ func writeHandshake(conn *network.Conn, cfg *global.Configure) error {
return conn.WriteMessage(&msg, 5*time.Second)
}
func (conn *Conn) isDrop(linkID string) bool {
conn.lockDrop.RLock()
defer conn.lockDrop.RUnlock()
_, ok := conn.drop[linkID]
return ok
}
func (conn *Conn) getChan(linkID string) chan *network.Msg {
conn.RLock()
ch := conn.read[linkID]
conn.RUnlock()
if ch == nil {
ch = conn.unknownRead
}
return ch
}
func (conn *Conn) hookDispatch(ch chan *network.Msg, msg *network.Msg) bool {
switch msg.GetXType() {
case network.Msg_disconnect:
conn.lockDrop.Lock()
conn.drop[msg.GetLinkId()] = time.Now().Add(dropBlockTimeout)
conn.lockDrop.Unlock()
conn.onDisconnect <- msg.GetLinkId()
logging.Info("connection %s disconnected", msg.GetLinkId())
return false
}
return true
}
func (conn *Conn) loopRead() {
defer utils.Recover("loopRead")
defer conn.close()
defer conn.cancel()
var timeout int
run := func(msg *network.Msg) bool {
timeout = 0
if msg.GetXType() == network.Msg_keepalive {
return true
}
logging.Debug("read message %s(%s) from %s",
msg.GetXType().String(), msg.GetLinkId(), msg.GetFrom())
linkID := msg.GetLinkId()
if conn.isDrop(linkID) {
return true
}
ch := conn.getChan(linkID)
if !conn.hookDispatch(ch, msg) {
return true
}
select {
case ch <- msg:
case <-time.After(conn.cfg.WriteTimeout):
logging.Error("drop message: %s", msg.GetXType().String())
conn.lockDrop.Lock()
conn.drop[msg.GetLinkId()] = time.Now().Add(dropBlockTimeout)
conn.lockDrop.Unlock()
case <-conn.ctx.Done():
return false
}
return true
}
for {
msg, _, err := conn.conn.ReadMessage(conn.cfg.ReadTimeout)
if err != nil {
@@ -106,36 +168,17 @@ func (conn *Conn) loopRead() {
}
continue
}
if strings.Contains(err.Error(), "use of closed network connection") {
logging.Error("read message: %v", err)
return
}
if err == io.EOF {
return
}
logging.Error("read message: %v", err)
continue
}
timeout = 0
if msg.GetXType() == network.Msg_keepalive {
continue
}
logging.Debug("read message %s(%s) from %s",
msg.GetXType().String(), msg.GetLinkId(), msg.GetFrom())
linkID := msg.GetLinkId()
conn.lockDrop.RLock()
_, drop := conn.drop[linkID]
conn.lockDrop.RUnlock()
if drop {
continue
}
conn.RLock()
ch := conn.read[linkID]
conn.RUnlock()
if ch == nil {
ch = conn.unknownRead
}
select {
case ch <- msg:
case <-time.After(conn.cfg.ReadTimeout):
logging.Error("drop message: %s", msg.GetXType().String())
conn.lockDrop.Lock()
conn.drop[msg.GetLinkId()] = time.Now().Add(time.Minute)
conn.lockDrop.Unlock()
case <-conn.ctx.Done():
if !run(msg) {
return
}
}
@@ -182,7 +225,7 @@ func (conn *Conn) AddLink(id string) {
logging.Info("add link %s", id)
conn.Lock()
if _, ok := conn.read[id]; !ok {
conn.read[id] = make(chan *network.Msg, 10)
conn.read[id] = make(chan *network.Msg, 1024)
}
conn.Unlock()
}
@@ -207,6 +250,11 @@ func (conn *Conn) ChanUnknown() <-chan *network.Msg {
return conn.unknownRead
}
// ChanDisconnect get channel of disconnect
func (conn *Conn) ChanDisconnect() <-chan string {
return conn.onDisconnect
}
func (conn *Conn) checkDrop() {
for {
time.Sleep(time.Second)
@@ -232,3 +280,18 @@ func (conn *Conn) checkDrop() {
func (conn *Conn) Wait() {
<-conn.ctx.Done()
}
// ChanClose close read chan
func (conn *Conn) ChanClose(id string) {
conn.Lock()
ch := conn.read[id]
if ch != nil {
close(ch)
}
delete(conn.read, id)
conn.Unlock()
conn.lockDrop.Lock()
conn.drop[id] = time.Now().Add(dropBlockTimeout)
conn.lockDrop.Unlock()
}
+178
View File
@@ -0,0 +1,178 @@
package conn
import (
"net/http"
"time"
"github.com/lwch/logging"
"github.com/lwch/natpass/code/network"
"google.golang.org/protobuf/proto"
)
func makeCodeHeader(header http.Header) map[string]*network.CodeHeaderValues {
ret := make(map[string]*network.CodeHeaderValues)
for key, values := range header {
data := make([]string, len(values))
copy(data, values)
ret[key] = &network.CodeHeaderValues{
Values: data,
}
}
return ret
}
// SendCodeRequest send request
func (conn *Conn) SendCodeRequest(to, linkID string, requestID uint64,
method, uri string, body []byte, header http.Header) uint64 {
var msg network.Msg
msg.To = to
msg.XType = network.Msg_code_request
msg.LinkId = linkID
msg.Payload = &network.Msg_Csreq{
Csreq: &network.CodeRequest{
RequestId: requestID,
Method: method,
Uri: uri,
Body: dup(body),
Header: makeCodeHeader(header),
},
}
select {
case conn.write <- &msg:
data, _ := proto.Marshal(&msg)
return uint64(len(data))
case <-time.After(conn.cfg.WriteTimeout):
logging.Info("send: droped %s", network.Msg_code_request.String())
return 0
}
}
// SendCodeConnect send connect
func (conn *Conn) SendCodeConnect(to, linkID string, requestID uint64,
uri string, header http.Header) uint64 {
var msg network.Msg
msg.To = to
msg.XType = network.Msg_code_connect
msg.LinkId = linkID
msg.Payload = &network.Msg_Csconn{
Csconn: &network.CodeConnect{
RequestId: requestID,
Uri: uri,
Header: makeCodeHeader(header),
},
}
select {
case conn.write <- &msg:
data, _ := proto.Marshal(&msg)
return uint64(len(data))
case <-time.After(conn.cfg.WriteTimeout):
logging.Info("send: droped %s", network.Msg_code_connect.String())
return 0
}
}
// SendCodeResponseHeader send response header
func (conn *Conn) SendCodeResponseHeader(to, linkID string, requestID uint64,
code uint32, header http.Header) uint64 {
var msg network.Msg
msg.To = to
msg.XType = network.Msg_code_response_hdr
msg.LinkId = linkID
msg.Payload = &network.Msg_CsrepHdr{
CsrepHdr: &network.CodeResponseHeader{
RequestId: requestID,
Code: code,
Header: makeCodeHeader(header),
},
}
select {
case conn.write <- &msg:
data, _ := proto.Marshal(&msg)
return uint64(len(data))
case <-time.After(conn.cfg.WriteTimeout):
logging.Info("send: droped %s", network.Msg_code_response_hdr.String())
return 0
}
}
// SendCodeResponseBody send response body
func (conn *Conn) SendCodeResponseBody(to, linkID string, requestID uint64,
idx uint32, ok, done bool, data []byte) uint64 {
var mask uint32
if ok {
mask |= 1
}
if done {
mask |= 2
}
var msg network.Msg
msg.To = to
msg.XType = network.Msg_code_response_body
msg.LinkId = linkID
msg.Payload = &network.Msg_CsrepBody{
CsrepBody: &network.CodeResponseBody{
RequestId: requestID,
Index: idx,
Mask: mask,
Body: dup(data),
},
}
select {
case conn.write <- &msg:
data, _ := proto.Marshal(&msg)
return uint64(len(data))
case <-time.After(conn.cfg.WriteTimeout):
logging.Info("send: droped %s", network.Msg_code_response_body.String())
return 0
}
}
// SendCodeResponseConnect send response connect
func (conn *Conn) SendCodeResponseConnect(to, linkID string, requestID uint64,
ok bool, msg string, header http.Header) uint64 {
var m network.Msg
m.To = to
m.XType = network.Msg_code_connect_response
m.LinkId = linkID
m.Payload = &network.Msg_CsconnRep{
CsconnRep: &network.CodeConnectResponse{
RequestId: requestID,
Ok: ok,
Msg: msg,
Header: makeCodeHeader(header),
},
}
select {
case conn.write <- &m:
data, _ := proto.Marshal(&m)
return uint64(len(data))
case <-time.After(conn.cfg.WriteTimeout):
logging.Info("send: droped %s", network.Msg_code_connect_response.String())
return 0
}
}
// SendCodeData send data
func (conn *Conn) SendCodeData(to, linkID string, requestID uint64,
ok bool, t int, body []byte) uint64 {
var m network.Msg
m.To = to
m.XType = network.Msg_code_data
m.LinkId = linkID
m.Payload = &network.Msg_Csdata{
Csdata: &network.CodeData{
RequestId: requestID,
Ok: ok,
Type: uint32(t),
Data: dup(body),
},
}
select {
case conn.write <- &m:
data, _ := proto.Marshal(&m)
return uint64(len(data))
case <-time.After(conn.cfg.WriteTimeout):
logging.Info("send: droped %s", network.Msg_code_data.String())
return 0
}
}
+7
View File
@@ -53,6 +53,13 @@ func (conn *Conn) SendConnectReq(id string, cfg global.Rule) {
XType: network.ConnectRequest_bench,
},
}
case "code-server":
msg.Payload = &network.Msg_Creq{
Creq: &network.ConnectRequest{
Name: cfg.Name,
XType: network.ConnectRequest_code,
},
}
}
select {
case conn.write <- &msg:
-5
View File
@@ -9,11 +9,6 @@ import (
// SendShellData send shell data
func (conn *Conn) SendShellData(to string, id string, data []byte) uint64 {
dup := func(data []byte) []byte {
ret := make([]byte, len(data))
copy(ret, data)
return ret
}
var msg network.Msg
msg.To = to
msg.XType = network.Msg_shell_data
-5
View File
@@ -10,11 +10,6 @@ import (
// SendVNCImage send vnc image data
func (conn *Conn) SendVNCImage(to string, id string, screen, rect image.Rectangle,
encode network.VncImageEncoding, data []byte) {
dup := func(data []byte) []byte {
ret := make([]byte, len(data))
copy(ret, data)
return ret
}
var msg network.Msg
msg.To = to
msg.XType = network.Msg_vnc_image
+7
View File
@@ -0,0 +1,7 @@
package conn
func dup(data []byte) []byte {
ret := make([]byte, len(data))
copy(ret, data)
return ret
}
+8 -5
View File
@@ -16,11 +16,14 @@ func (db *Dashboard) Info(w http.ResponseWriter, r *http.Request) {
}
ret.Rules = len(db.cfg.Rules)
db.mgr.Range(func(t rule.Rule) {
n := len(t.GetLinks())
ret.VirtualLinks += n
if t.GetTypeName() == "shell" ||
t.GetTypeName() == "vnc" {
ret.Session += n
lr, ok := t.(rule.LinkedRule)
if ok {
n := len(lr.GetLinks())
ret.VirtualLinks += n
if t.GetTypeName() == "shell" ||
t.GetTypeName() == "vnc" {
ret.Session += n
}
}
})
w.Header().Set("Content-Type", "application/json")
+13 -8
View File
@@ -18,24 +18,29 @@ func (db *Dashboard) Rules(w http.ResponseWriter, r *http.Request) {
}
type item struct {
Name string `json:"name"`
Remote string `json:"remote"`
Remote string `json:"remote,omitempty"`
Port uint16 `json:"port"`
Type string `json:"type"`
Links []link `json:"links"`
}
var ret []item
db.mgr.Range(func(t rule.Rule) {
lr, isLR := t.(rule.LinkedRule)
var it item
it.Name = t.GetName()
it.Remote = t.GetRemote()
if isLR {
it.Remote = lr.GetRemote()
}
it.Port = t.GetPort()
it.Type = t.GetTypeName()
for _, l := range t.GetLinks() {
var lk link
lk.ID = l.GetID()
lk.RecvBytes, lk.SendBytes = l.GetBytes()
lk.RecvPacket, lk.SendPacket = l.GetPackets()
it.Links = append(it.Links, lk)
if isLR {
for _, l := range lr.GetLinks() {
var lk link
lk.ID = l.GetID()
lk.RecvBytes, lk.SendBytes = l.GetBytes()
lk.RecvPacket, lk.SendPacket = l.GetPackets()
it.Links = append(it.Links, lk)
}
}
ret = append(ret, it)
})
+10 -2
View File
@@ -42,6 +42,7 @@ type Configure struct {
DashboardListen string
DashboardPort uint16
Rules []Rule
CodeDir string
}
// LoadConf load configure file
@@ -65,12 +66,13 @@ func LoadConf(dir string) *Configure {
Listen string `yaml:"listen"`
Port uint16 `yaml:"port"`
} `yaml:"dashboard"`
Rules []Rule `yaml:"rules"`
Rules []Rule `yaml:"rules"`
CodeDir string `yaml:"codedir"`
}
runtime.Assert(yaml.Decode(dir, &cfg))
for i, t := range cfg.Rules {
switch t.Type {
case "shell", "vnc", "bench":
case "shell", "vnc", "bench", "code-server":
default:
panic(fmt.Sprintf("unsupported type: %s", t.Type))
}
@@ -87,6 +89,11 @@ func LoadConf(dir string) *Configure {
runtime.Assert(err)
cfg.Log.Dir = filepath.Join(filepath.Dir(dir), cfg.Log.Dir)
}
if !filepath.IsAbs(cfg.CodeDir) {
dir, err := os.Executable()
runtime.Assert(err)
cfg.CodeDir = filepath.Join(filepath.Dir(dir), cfg.CodeDir)
}
return &Configure{
ID: cfg.ID,
Server: cfg.Server,
@@ -101,5 +108,6 @@ func LoadConf(dir string) *Configure {
DashboardListen: cfg.Dashboard.Listen,
DashboardPort: cfg.Dashboard.Port,
Rules: cfg.Rules,
CodeDir: cfg.CodeDir,
}
}
+2 -1
View File
@@ -104,7 +104,8 @@ func main() {
switch *act {
case "install":
runtime.Assert(sv.Install())
utils.BuildLogDir(cfg.LogDir, *user)
utils.BuildDir(cfg.LogDir, *user)
utils.BuildDir(cfg.CodeDir, *user)
case "uninstall":
runtime.Assert(sv.Uninstall())
default:
+1
View File
@@ -0,0 +1 @@
/assets.go
+164
View File
@@ -0,0 +1,164 @@
package code
import (
"errors"
"fmt"
"net"
"net/http"
"sync"
"time"
"github.com/lwch/logging"
"github.com/lwch/natpass/code/client/conn"
"github.com/lwch/natpass/code/client/global"
"github.com/lwch/natpass/code/client/rule"
"github.com/lwch/natpass/code/network"
"github.com/lwch/runtime"
)
// Code code-server handler
type Code struct {
sync.RWMutex
Name string
cfg global.Rule
workspace map[string]*Workspace
readTimeout time.Duration
writeTimeout time.Duration
}
// New new code-server handler
func New(cfg global.Rule, readTimeout, writeTimeout time.Duration) *Code {
return &Code{
Name: cfg.Name,
cfg: cfg,
workspace: make(map[string]*Workspace),
readTimeout: readTimeout,
writeTimeout: writeTimeout,
}
}
// GetName get code-server rule name
func (code *Code) GetName() string {
return code.Name
}
// GetTypeName get code-server rule type name
func (code *Code) GetTypeName() string {
return "code-server"
}
// GetPort get listen port
func (code *Code) GetPort() uint16 {
return code.cfg.LocalPort
}
// GetTarget get target of this rule
func (code *Code) GetTarget() string {
return code.cfg.Target
}
// GetLinks get rule links
func (code *Code) GetLinks() []rule.Link {
ret := make([]rule.Link, 0, len(code.workspace))
code.RLock()
for _, link := range code.workspace {
ret = append(ret, link)
}
code.RUnlock()
return ret
}
// GetRemote get remote target name
func (code *Code) GetRemote() string {
return code.cfg.Target
}
// NewLink new link
func (code *Code) NewLink(id, remote string, localConn net.Conn, remoteConn *conn.Conn) rule.Link {
remoteConn.AddLink(id)
ws := newWorkspace(code, id, code.cfg.Name, remote, remoteConn)
code.Lock()
code.workspace[ws.id] = ws
code.Unlock()
return ws
}
// OnDisconnect on disconnect message
func (code *Code) OnDisconnect(id string) {
code.RLock()
workspace := code.workspace[id]
code.RUnlock()
if workspace != nil {
workspace.Close(false)
}
}
// Handle handle code-server
func (code *Code) Handle(c *conn.Conn) {
defer func() {
if err := recover(); err != nil {
logging.Error("close code-server: %s, err=%v", code.Name, err)
}
}()
pf := func(cb func(*conn.Conn, http.ResponseWriter, *http.Request)) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
cb(c, w, r)
}
}
mux := http.NewServeMux()
mux.HandleFunc("/new", pf(code.New))
mux.HandleFunc("/info", code.Info)
mux.HandleFunc("/forward/", pf(code.Forward))
mux.HandleFunc("/", pf(code.Render))
svr := &http.Server{
Addr: fmt.Sprintf("%s:%d", code.cfg.LocalAddr, code.cfg.LocalPort),
Handler: mux,
}
runtime.Assert(svr.ListenAndServe())
}
func (code *Code) remove(id string) {
code.Lock()
delete(code.workspace, id)
code.Unlock()
}
func (code *Code) new(conn *conn.Conn) (string, error) {
id, err := runtime.UUID(16, "0123456789abcdef")
if err != nil {
logging.Error("failed to generate link_id for code-server: %s, err=%v",
code.Name, err)
return "", err
}
link := code.NewLink(id, code.cfg.Target, nil, conn).(*Workspace)
conn.SendConnectReq(id, code.cfg)
ch := conn.ChanRead(id)
var repMsg *network.Msg
for {
var msg *network.Msg
select {
case msg = <-ch:
case <-time.After(time.Minute):
logging.Error("create code-server %s by rule %s failed, timtout", link.id, link.parent.Name)
return "", errWaitingTimeout
}
if msg.GetXType() != network.Msg_connect_rep {
conn.Reset(id, msg)
time.Sleep(code.readTimeout / 10)
continue
}
rep := msg.GetCrep()
if !rep.GetOk() {
logging.Error("create code-server %s by rule %s failed, err=%s",
link.id, link.parent.Name, rep.GetMsg())
return "", errors.New(rep.GetMsg())
}
repMsg = msg
break
}
logging.Info("create link %s for code-server rule [%s] from %s to %s",
link.GetID(), code.cfg.Name,
repMsg.GetTo(), repMsg.GetFrom())
go link.localRead()
return id, nil
}
+71
View File
@@ -0,0 +1,71 @@
package code
import (
"net/http"
"strings"
"github.com/lwch/logging"
"github.com/lwch/natpass/code/client/conn"
)
// Forward forward code-server requests
func (code *Code) Forward(conn *conn.Conn, w http.ResponseWriter, r *http.Request) {
srcPath := r.URL.Path
srcQuery := r.URL.Query()
name := strings.TrimPrefix(r.URL.Path, "/forward/")
name = name[:strings.Index(name, "/")]
r.URL.Path = strings.TrimPrefix(r.URL.Path, "/forward/"+name)
if len(r.URL.Path) == 0 {
r.URL.Path = "/"
}
var id string
const argName = "natpass_connection_id"
if r.URL.Path == "/" && len(r.FormValue(argName)) == 0 {
var err error
id, err = code.new(conn)
if err != nil {
logging.Error("can not create workspace for [%s]: %v", code.Name, err)
http.Error(w, err.Error(), http.StatusBadGateway)
return
}
http.SetCookie(w, &http.Cookie{
Name: "__NATPASS_CONNECTION_ID__",
Value: id,
})
srcQuery.Set(argName, id)
http.Redirect(w, r, srcPath+"?"+srcQuery.Encode(), http.StatusTemporaryRedirect)
return
}
cookie, err := r.Cookie("__NATPASS_CONNECTION_ID__")
if err != nil {
logging.Error("get connection id: %v", err)
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
id = cookie.Value
code.RLock()
workspace := code.workspace[id]
code.RUnlock()
if workspace == nil {
http.NotFound(w, r)
return
}
if code.isWebsocket(r) {
code.handleWebsocket(workspace, w, r)
} else {
code.handleRequest(conn, workspace, w, r)
}
}
func (code *Code) isWebsocket(r *http.Request) bool {
upgrade := r.Header.Get("Connection")
return upgrade == "Upgrade"
}
@@ -0,0 +1,83 @@
package code
import (
"bytes"
"fmt"
"io"
"net/http"
"github.com/lwch/logging"
"github.com/lwch/natpass/code/client/conn"
"github.com/lwch/natpass/code/network"
)
func (code *Code) handleRequest(conn *conn.Conn, workspace *Workspace, w http.ResponseWriter, r *http.Request) {
reqID, err := workspace.SendRequest(r)
if err != nil {
logging.Error("send_request: %v", err)
http.Error(w, err.Error(), http.StatusBadGateway)
return
}
defer workspace.closeMessage(reqID)
resp := workspace.onResponse(reqID)
if resp == nil {
logging.Error("waiting for [%s] [%s] no response for request, uri=%s, request_id=%d",
workspace.id, workspace.name, r.URL.Path, reqID)
http.Error(w, "no response", http.StatusInternalServerError)
return
}
if resp.GetXType() != network.Msg_code_response_hdr {
logging.Error("got invalid message type [%s] [%s]: %s",
workspace.id, workspace.name, resp.GetXType().String())
http.Error(w, "invalid message type", http.StatusServiceUnavailable)
return
}
hdr := resp.GetCsrepHdr()
for key, values := range hdr.GetHeader() {
for _, v := range values.GetValues() {
w.Header().Add(key, v)
}
}
var idx uint32
var buf bytes.Buffer
for {
msg := workspace.onResponse(reqID)
if msg == nil {
logging.Error("no response [%s] [%s]", workspace.id, workspace.name)
http.Error(w, "no response", http.StatusBadGateway)
return
}
if msg.GetXType() != network.Msg_code_response_body {
logging.Error("got invalid message type [%s] [%s]: %s",
workspace.id, workspace.name, resp.GetXType().String())
http.Error(w, "invalid message type", http.StatusServiceUnavailable)
return
}
resp := msg.GetCsrepBody()
if resp.GetIndex() != idx {
logging.Error("loss data [%s] [%s]", workspace.id, workspace.name)
http.Error(w, "loss data", http.StatusResetContent)
return
}
if resp.GetMask()&1 == 0 {
logging.Error("read data [%s] [%s]: %s", workspace.id, workspace.name, string(resp.GetBody()))
http.Error(w, fmt.Sprintf("read error: %s", string(resp.GetBody())), http.StatusResetContent)
return
}
_, err = io.Copy(&buf, bytes.NewReader(resp.GetBody()))
if err != nil {
logging.Error("write body: %v", err)
http.Error(w, fmt.Sprintf("save data: %v", err), http.StatusInternalServerError)
return
}
if resp.GetMask()&2 > 0 {
w.WriteHeader(int(hdr.GetCode()))
io.Copy(w, &buf)
return
}
idx++
}
}
@@ -0,0 +1,62 @@
package code
import (
"net/http"
"sync"
"github.com/gorilla/websocket"
"github.com/lwch/logging"
"github.com/lwch/natpass/code/network"
)
var upgrader = websocket.Upgrader{
EnableCompression: true,
}
func (code *Code) handleWebsocket(workspace *Workspace, w http.ResponseWriter, r *http.Request) {
reqID, err := workspace.SendConnect(r)
if err != nil {
logging.Error("send_connect: %v", err)
http.Error(w, err.Error(), http.StatusBadGateway)
return
}
defer workspace.closeMessage(reqID)
resp := workspace.onResponse(reqID)
if resp == nil {
logging.Error("waiting for [%s] [%s] no response for websocket, request_id=%d",
workspace.id, workspace.name, reqID)
http.Error(w, "no response", http.StatusInternalServerError)
return
}
if resp.GetXType() != network.Msg_code_connect_response {
logging.Error("got invalid message type [%s] [%s]: %s",
workspace.id, workspace.name, resp.GetXType().String())
http.Error(w, "invalid message type", http.StatusServiceUnavailable)
return
}
response := resp.GetCsconnRep()
if !response.GetOk() {
logging.Error("can not create websocket connection [%s] [%s]: %s",
workspace.id, workspace.name, response.GetMsg())
http.Error(w, response.GetMsg(), http.StatusBadGateway)
return
}
local, err := upgrader.Upgrade(w, r, nil)
if err != nil {
logging.Error("upgrade websocket connection [%s] [%s]: %v",
workspace.id, workspace.name, err)
http.Error(w, err.Error(), http.StatusBadGateway)
return
}
defer local.Close()
var wg sync.WaitGroup
wg.Add(2)
go workspace.ws2remote(&wg, reqID, local)
go workspace.remote2ws(&wg, reqID, local)
wg.Wait()
}
+34
View File
@@ -0,0 +1,34 @@
package code
import (
"encoding/json"
"net/http"
"github.com/lwch/logging"
)
// Info get workspace info
func (code *Code) Info(w http.ResponseWriter, r *http.Request) {
id := r.FormValue("id")
code.RLock()
workspace := code.workspace[id]
code.RUnlock()
if workspace == nil {
http.NotFound(w, r)
return
}
data, err := json.Marshal(map[string]interface{}{
"name": code.Name,
"send_bytes": workspace.sendBytes,
"send_packet": workspace.sendPacket,
"recv_bytes": workspace.recvBytes,
"recv_packet": workspace.recvPacket,
})
if err != nil {
logging.Error("marshal: %v", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.Write(data)
}
+12
View File
@@ -0,0 +1,12 @@
package code
import (
"net/http"
"github.com/lwch/natpass/code/client/conn"
)
// New new code-server workspace
func (code *Code) New(conn *conn.Conn, w http.ResponseWriter, r *http.Request) {
w.Write([]byte(code.cfg.Name))
}
+35
View File
@@ -0,0 +1,35 @@
package code
import (
"bytes"
"io"
"mime"
"net/http"
"path/filepath"
"strings"
"text/template"
"github.com/lwch/natpass/code/client/conn"
)
// Render render code-server
func (code *Code) Render(conn *conn.Conn, w http.ResponseWriter, r *http.Request) {
dir := strings.TrimPrefix(r.URL.Path, "/")
data, err := Asset(dir)
if err == nil {
ctype := mime.TypeByExtension(filepath.Ext(dir))
if ctype == "" {
ctype = http.DetectContentType(data)
}
w.Header().Set("Content-Type", ctype)
io.Copy(w, bytes.NewReader(data))
return
}
data, _ = Asset("index.html")
tpl, err := template.New("all").Parse(string(data))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
tpl.Execute(w, code)
}
+274
View File
@@ -0,0 +1,274 @@
package code
import (
"bufio"
"errors"
"io"
"net"
"net/http"
"os"
"os/exec"
"path/filepath"
"strings"
"sync"
"time"
"github.com/gorilla/websocket"
"github.com/lwch/logging"
"github.com/lwch/natpass/code/client/conn"
"github.com/lwch/natpass/code/network"
"github.com/lwch/natpass/code/utils"
"google.golang.org/protobuf/proto"
)
var errWaitingTimeout = errors.New("waiting for code-server startup more than 1 minute")
// Workspace workspace of code-server
type Workspace struct {
sync.RWMutex
parent *Code
id string
target string
name string
exec *exec.Cmd
cli *http.Client
dailer websocket.Dialer
remote *conn.Conn
// runtime
sendBytes uint64
recvBytes uint64
sendPacket uint64
recvPacket uint64
requestID uint64
onListen chan struct{}
onMessage map[uint64]chan *network.Msg
}
func newWorkspace(parent *Code, id, name, target string, remote *conn.Conn) *Workspace {
name = strings.ReplaceAll(name, "/", "_")
name = strings.ReplaceAll(name, "\\", "_")
return &Workspace{
parent: parent,
id: id,
target: target,
name: name,
remote: remote,
onListen: make(chan struct{}),
onMessage: make(map[uint64]chan *network.Msg),
}
}
// GetID get link id
func (ws *Workspace) GetID() string {
return ws.id
}
// GetBytes get send and recv bytes
func (ws *Workspace) GetBytes() (uint64, uint64) {
return ws.recvBytes, ws.sendBytes
}
// GetPackets get send and recv packets
func (ws *Workspace) GetPackets() (uint64, uint64) {
return ws.recvPacket, ws.sendPacket
}
// Exec execute code-server
func (ws *Workspace) Exec(dir string) error {
workdir := filepath.Join(dir, ws.name)
err := os.MkdirAll(workdir, 0755)
if err != nil {
logging.Error("can not create work dir[%s]: %v", workdir, err)
return err
}
sockDir := filepath.Join(workdir, ws.id+".sock")
logging.Info("EXTENSIONS_GALLERY=%s", os.Getenv("EXTENSIONS_GALLERY"))
ws.exec = exec.Command("code-server",
"--auth", "none",
"--socket", sockDir,
"--user-data-dir", filepath.Join(workdir, "data"),
"--extensions-dir", filepath.Join(workdir, "extensions"),
"--config", filepath.Join(workdir, "conf"))
ws.exec.Env = os.Environ()
stdout, err := ws.exec.StdoutPipe()
if err != nil {
logging.Error("can not get stdout pipe for link [%s] name [%s]", ws.id, ws.name)
return err
}
stderr, err := ws.exec.StderrPipe()
if err != nil {
logging.Error("can not get stderr pipe for link [%s] name [%s]", ws.id, ws.name)
return err
}
err = ws.exec.Start()
if err != nil {
logging.Error("can not start code-server for link [%s] name [%s]", ws.id, ws.name)
return err
}
go func() {
err = ws.exec.Wait()
if err != nil {
logging.Error("code-server [%s] [%s] exited: %v", ws.id, ws.name, err)
return
}
logging.Info("code-server for link [%s] name [%s] exited", ws.id, ws.name)
}()
ws.cli = &http.Client{
Transport: &http.Transport{
Dial: func(network, addr string) (net.Conn, error) {
return net.Dial("unix", sockDir)
},
},
}
ws.dailer = websocket.Dialer{
NetDial: func(network, addr string) (net.Conn, error) {
return net.Dial("unix", sockDir)
},
}
go ws.log(stdout, stderr)
select {
case <-time.After(time.Minute):
return errWaitingTimeout
case <-ws.onListen:
return nil
}
}
// Close close workspace
func (ws *Workspace) Close(send bool) {
if ws.exec != nil && ws.exec.Process != nil {
ws.exec.Process.Kill()
}
if send {
ws.remote.SendDisconnect(ws.target, ws.id)
}
ws.parent.remove(ws.id)
ws.remote.ChanClose(ws.id)
}
func (ws *Workspace) log(stdout, stderr io.ReadCloser) {
defer stdout.Close()
defer stderr.Close()
var wg sync.WaitGroup
wg.Add(2)
watch := func(target io.Reader) {
defer wg.Done()
s := bufio.NewScanner(target)
for s.Scan() {
if strings.Contains(s.Text(), "listening on") &&
strings.Contains(s.Text(), ws.id+".sock") {
ws.onListen <- struct{}{}
}
logging.Info("code-server [%s] [%s]: %s", ws.id, ws.name, s.Text())
}
}
go watch(stdout)
go watch(stderr)
wg.Wait()
}
// Forward forward data from remote node
func (ws *Workspace) Forward() {
go ws.remoteRead()
}
func (ws *Workspace) remoteRead() {
defer utils.Recover("remoteRead")
defer ws.Close(true)
ch := ws.remote.ChanRead(ws.id)
for {
msg := <-ch
if msg == nil {
return
}
data, _ := proto.Marshal(msg)
ws.recvBytes += uint64(len(data))
ws.recvPacket++
switch msg.GetXType() {
case network.Msg_code_request:
go ws.handleRequest(msg)
case network.Msg_code_connect:
ws.Lock()
ws.onMessage[msg.GetCsconn().GetRequestId()] = make(chan *network.Msg, 1024)
ws.Unlock()
go ws.handleConnect(msg)
case network.Msg_code_data:
ws.writeMessage(msg.GetCsdata().GetRequestId(), msg)
}
}
}
func (ws *Workspace) closeMessage(reqID uint64) {
ws.Lock()
if ch, ok := ws.onMessage[reqID]; ok {
close(ch)
delete(ws.onMessage, reqID)
}
ws.Unlock()
}
func (ws *Workspace) localRead() {
defer utils.Recover("localRead")
defer ws.Close(true)
ch := ws.remote.ChanRead(ws.id)
for {
msg := <-ch
if msg == nil {
return
}
data, _ := proto.Marshal(msg)
ws.recvBytes += uint64(len(data))
ws.recvPacket++
switch msg.GetXType() {
case network.Msg_code_response_hdr:
ws.writeMessage(msg.GetCsrepHdr().GetRequestId(), msg)
case network.Msg_code_response_body:
ws.writeMessage(msg.GetCsrepBody().GetRequestId(), msg)
case network.Msg_code_connect_response:
ws.writeMessage(msg.GetCsconnRep().GetRequestId(), msg)
case network.Msg_code_data:
ws.writeMessage(msg.GetCsdata().GetRequestId(), msg)
}
}
}
func (ws *Workspace) writeMessage(reqID uint64, msg *network.Msg) {
defer utils.Recover("writeMessage")
ws.RLock()
ch := ws.onMessage[reqID]
ws.RUnlock()
if ch != nil {
select {
case ch <- msg:
case <-time.After(ws.parent.writeTimeout):
logging.Error("code-server [%s] [%s]: message %s droped",
ws.id, ws.name, msg.GetXType().String())
}
}
}
func (ws *Workspace) chanResponse(reqID uint64) <-chan *network.Msg {
ws.RLock()
defer ws.RUnlock()
return ws.onMessage[reqID]
}
func (ws *Workspace) onResponse(reqID uint64) *network.Msg {
ws.RLock()
ch := ws.onMessage[reqID]
ws.RUnlock()
if ch != nil {
select {
case msg := <-ch:
return msg
case <-time.After(ws.parent.readTimeout):
logging.Info("code-server [%s] [%s]: waiting for request %d timeout",
ws.id, ws.name, reqID)
return nil
}
}
return nil
}
@@ -0,0 +1,56 @@
package code
import (
"io/ioutil"
"net/http"
"strings"
"sync/atomic"
"github.com/lwch/logging"
"github.com/lwch/natpass/code/network"
)
// SendRequest send request from local node
func (ws *Workspace) SendRequest(r *http.Request) (uint64, error) {
reqID := atomic.AddUint64(&ws.requestID, 1)
body, err := ioutil.ReadAll(r.Body)
if err != nil {
logging.Error("send request for workspace [%s] [%s]: %v", ws.id, ws.name, err)
return 0, err
}
ws.Lock()
ws.onMessage[reqID] = make(chan *network.Msg, 1024)
ws.Unlock()
send := ws.remote.SendCodeRequest(ws.target, ws.id, reqID,
r.Method, r.URL.RequestURI(), body, r.Header)
ws.sendBytes += send
ws.sendPacket++
return reqID, nil
}
// SendConnect send websocket connect action from local node
func (ws *Workspace) SendConnect(r *http.Request) (uint64, error) {
reqID := atomic.AddUint64(&ws.requestID, 1)
ws.Lock()
ws.onMessage[reqID] = make(chan *network.Msg, 1024)
ws.Unlock()
hdr := make(http.Header)
for key, values := range r.Header {
if strings.HasPrefix(key, "Sec-") {
continue
}
for _, value := range values {
hdr.Add(key, value)
}
}
hdr.Del("Connection")
hdr.Del("Upgrade")
send := ws.remote.SendCodeConnect(ws.target, ws.id, reqID,
r.URL.RequestURI(), hdr)
ws.sendBytes += send
ws.sendPacket++
return reqID, nil
}
@@ -0,0 +1,160 @@
package code
import (
"bytes"
"io"
"net/http"
"sync"
"github.com/gorilla/websocket"
"github.com/lwch/logging"
"github.com/lwch/natpass/code/network"
"github.com/lwch/natpass/code/utils"
)
func (ws *Workspace) handleRequest(msg *network.Msg) {
defer utils.Recover("handleRequest")
req := msg.GetCsreq()
request, err := http.NewRequest(req.GetMethod(), "http://unix"+req.GetUri(), bytes.NewReader(req.GetBody()))
if err != nil {
logging.Error("build request [%s] [%s]: %v", ws.id, ws.name, err)
ws.remote.SendCodeResponseHeader(ws.target, ws.id, req.GetRequestId(),
http.StatusInternalServerError, nil)
ws.remote.SendCodeResponseBody(ws.target, ws.id, req.GetRequestId(),
0, false, true, []byte(err.Error()))
return
}
for key, values := range req.GetHeader() {
for _, v := range values.GetValues() {
request.Header.Add(key, v)
}
}
response, err := ws.cli.Do(request)
if err != nil {
logging.Error("call request [%s] [%s] [%s]: %v", ws.id, ws.name, req.GetUri(), err)
ws.remote.SendCodeResponseHeader(ws.target, ws.id, req.GetRequestId(),
http.StatusInternalServerError, nil)
ws.remote.SendCodeResponseBody(ws.target, ws.id, req.GetRequestId(),
0, false, true, []byte(err.Error()))
return
}
defer response.Body.Close()
send := ws.remote.SendCodeResponseHeader(ws.target, ws.id, req.GetRequestId(), uint32(response.StatusCode), response.Header)
ws.sendBytes += send
ws.sendPacket++
buf := make([]byte, 32*1024) // 32k block read
var idx uint32
for {
n, err := response.Body.Read(buf)
if err != nil {
if err == io.EOF {
send := ws.remote.SendCodeResponseBody(ws.target, ws.id, req.GetRequestId(), idx, true, true, buf[:n])
ws.sendBytes += send
ws.sendPacket++
return
}
send := ws.remote.SendCodeResponseBody(ws.target, ws.id, req.GetRequestId(), idx, false, true, []byte(err.Error()))
ws.sendBytes += send
ws.sendPacket++
logging.Error("call request [%s] [%s] [%s] read response data: %v", ws.id, ws.name, req.GetUri(), err)
return
}
send := ws.remote.SendCodeResponseBody(ws.target, ws.id, req.GetRequestId(), idx, true, false, buf[:n])
ws.sendBytes += send
ws.sendPacket++
idx++
}
}
func (ws *Workspace) handleConnect(msg *network.Msg) {
defer utils.Recover("handleConnect")
connect := msg.GetCsconn()
hdr := make(http.Header)
for key, values := range connect.GetHeader() {
for _, value := range values.GetValues() {
hdr.Add(key, value)
}
}
remote, resp, err := ws.dailer.Dial("ws://unix"+connect.GetUri(), hdr)
if err != nil {
logging.Error("dial websocket [%s] [%s]: %v", ws.id, ws.name, err)
send := ws.remote.SendCodeResponseConnect(ws.target, ws.id, connect.GetRequestId(),
false, err.Error(), nil)
ws.sendBytes += send
ws.sendPacket++
return
}
defer remote.Close()
defer resp.Body.Close()
send := ws.remote.SendCodeResponseConnect(ws.target, ws.id, connect.GetRequestId(),
true, "", resp.Header)
ws.sendBytes += send
ws.sendPacket++
var wg sync.WaitGroup
wg.Add(2)
go ws.ws2remote(&wg, connect.GetRequestId(), remote)
go ws.remote2ws(&wg, connect.GetRequestId(), remote)
wg.Wait()
}
func (ws *Workspace) ws2remote(wg *sync.WaitGroup, reqID uint64, conn *websocket.Conn) {
defer wg.Done()
defer conn.Close()
defer ws.closeMessage(reqID)
for {
t, data, err := conn.ReadMessage()
if err != nil {
logging.Error("read_message [%s] [%s]: %v", ws.id, ws.name, err)
ws.SendData(reqID, false, websocket.TextMessage, []byte(err.Error()))
return
}
ws.SendData(reqID, true, t, data)
}
}
// SendData send websocket data
func (ws *Workspace) SendData(reqID uint64, ok bool, t int, body []byte) {
for i := 0; i < len(body); i += 32 * 1024 {
end := i + 32*1024
if end > len(body) {
end = len(body)
}
send := ws.remote.SendCodeData(ws.target, ws.id, reqID,
ok, t, body[i:end])
ws.sendBytes += send
ws.sendPacket++
}
}
func (ws *Workspace) remote2ws(wg *sync.WaitGroup, reqID uint64, conn *websocket.Conn) {
defer wg.Done()
defer conn.Close()
defer ws.closeMessage(reqID)
ch := ws.chanResponse(reqID)
for {
msg := <-ch
if msg == nil {
return
}
if msg.GetXType() != network.Msg_code_data {
logging.Error("got invalid message type [%s] [%s]: %s",
ws.id, ws.name, msg.GetXType().String())
return
}
data := msg.GetCsdata()
if !data.GetOk() {
logging.Error("read message [%s] [%s]: %s",
ws.id, ws.name, string(data.GetData()))
return
}
err := conn.WriteMessage(int(data.GetType()), data.GetData())
if err != nil {
logging.Error("write_message [%s] [%s]: %v", ws.id, ws.name, err)
return
}
}
}
+29 -7
View File
@@ -18,13 +18,18 @@ type Link interface {
// Rule rule interface
type Rule interface {
NewLink(id, remote string, localConn net.Conn, remoteConn *conn.Conn) Link
GetName() string
GetRemote() string
GetPort() uint16
GetTypeName() string
}
// LinkedRule linked rule interface
type LinkedRule interface {
NewLink(id, remote string, localConn net.Conn, remoteConn *conn.Conn) Link
GetRemote() string
GetTarget() string
GetLinks() []Link
OnDisconnect(string)
}
// Mgr rule manager
@@ -45,13 +50,17 @@ func (mgr *Mgr) Add(rule Rule) {
mgr.rules = append(mgr.rules, rule)
}
// Get get rule by name
func (mgr *Mgr) Get(name, remote string) Rule {
// GetLinked get rule by name
func (mgr *Mgr) GetLinked(name, remote string) LinkedRule {
mgr.RLock()
defer mgr.RUnlock()
for _, t := range mgr.rules {
if t.GetName() == name && t.GetRemote() == remote {
return t
for _, r := range mgr.rules {
lr, ok := r.(LinkedRule)
if !ok {
continue
}
if r.GetName() == name && lr.GetRemote() == remote {
return lr
}
}
return nil
@@ -65,3 +74,16 @@ func (mgr *Mgr) Range(fn func(Rule)) {
fn(t)
}
}
// OnDisconnect on disconnect message
func (mgr *Mgr) OnDisconnect(id string) {
var links []LinkedRule
mgr.Range(func(r Rule) {
if lr, ok := r.(LinkedRule); ok {
links = append(links, lr)
}
})
for _, link := range links {
go link.OnDisconnect(id)
}
}
+2 -6
View File
@@ -47,7 +47,7 @@ func (shell *Shell) localForward(id string, local *websocket.Conn) {
shell.RLock()
link := shell.links[id]
shell.RUnlock()
defer link.Close()
defer link.Close(true)
for {
_, data, err := local.ReadMessage()
if err != nil {
@@ -66,7 +66,7 @@ func (shell *Shell) remoteForward(id string, local *websocket.Conn) {
link := shell.links[id]
shell.RUnlock()
ch := link.remote.ChanRead(id)
defer link.Close()
defer link.Close(true)
for {
msg := <-ch
if msg == nil {
@@ -84,10 +84,6 @@ func (shell *Shell) remoteForward(id string, local *websocket.Conn) {
}
logging.Debug("remote read %d bytes: name=%s, id=%s",
len(msg.GetSdata().GetData()), shell.Name, id)
case network.Msg_disconnect:
logging.Info("shell %s by rule %s closed by remote",
link.id, link.parent.Name)
return
}
}
}
+7 -7
View File
@@ -45,14 +45,17 @@ func (link *Link) GetPackets() (uint64, uint64) {
}
// Close close link
func (link *Link) Close() {
func (link *Link) Close(send bool) {
link.onClose()
p, err := os.FindProcess(link.pid)
if err == nil {
p.Kill()
}
link.remote.SendDisconnect(link.target, link.id)
if send {
link.remote.SendDisconnect(link.target, link.id)
}
link.parent.remove(link.id)
link.remote.ChanClose(link.id)
}
// Forward forward data
@@ -63,7 +66,7 @@ func (link *Link) Forward() {
func (link *Link) remoteRead() {
defer utils.Recover("remoteRead")
defer link.Close()
defer link.Close(true)
ch := link.remote.ChanRead(link.id)
for {
msg := <-ch
@@ -84,16 +87,13 @@ func (link *Link) remoteRead() {
link.parent.Name, link.id, err)
return
}
case network.Msg_disconnect:
logging.Info("shell %s link %s closed by remote", link.parent.Name, link.id)
return
}
}
}
func (link *Link) localRead() {
defer utils.Recover("localRead")
defer link.Close()
defer link.Close(true)
buf := make([]byte, 16*1024)
for {
n, err := link.stdout.Read(buf)
+10
View File
@@ -86,6 +86,16 @@ func (shell *Shell) GetPort() uint16 {
return shell.cfg.LocalPort
}
// OnDisconnect on disconnect message
func (shell *Shell) OnDisconnect(id string) {
shell.RLock()
link := shell.links[id]
shell.RUnlock()
if link != nil {
link.Close(false)
}
}
// Handle handle shell
func (shell *Shell) Handle(c *conn.Conn) {
defer func() {
+1 -1
View File
@@ -15,7 +15,7 @@ import (
// New new vnc
func (v *VNC) New(conn *conn.Conn, w http.ResponseWriter, r *http.Request) {
if v.link != nil {
v.link.close()
v.link.Close(true)
}
q := r.FormValue("quality")
s := r.FormValue("show_cursor")
+9 -7
View File
@@ -82,7 +82,7 @@ func (link *Link) Forward() {
}
func (link *Link) remoteRead() {
defer link.close()
defer link.Close(true)
ch := link.remote.ChanRead(link.id)
for {
msg := <-ch
@@ -110,9 +110,6 @@ func (link *Link) remoteRead() {
data := link.ps.GetClipboard()
link.remote.SendVNCClipboardData(link.target, link.id, true, data)
}
case network.Msg_disconnect:
logging.Info("link %s disconnected", link.id)
return
}
}
}
@@ -120,7 +117,7 @@ func (link *Link) remoteRead() {
func (link *Link) localRead() {
// TODO: exit by context
defer utils.Recover("capture")
defer link.close()
defer link.Close(true)
img, err := link.ps.Capture(3 * time.Second)
if err != nil {
logging.Error("capture: %v", err)
@@ -152,11 +149,16 @@ func (link *Link) localRead() {
}
}
func (link *Link) close() {
// Close close link
func (link *Link) Close(send bool) {
if link.ps != nil {
link.ps.Close()
}
link.remote.SendDisconnect(link.target, link.id)
if send {
link.remote.SendDisconnect(link.target, link.id)
}
link.parent.remove(link.id)
link.remote.ChanClose(link.id)
}
func cut(src *image.RGBA, rect image.Rectangle) *image.RGBA {
+10 -1
View File
@@ -47,7 +47,7 @@ func (v *VNC) NewLink(id, remote string, localConn net.Conn, remoteConn *conn.Co
remote: remoteConn,
}
if v.link != nil {
v.link.close()
v.link.Close(true)
}
v.link = link
return link
@@ -86,6 +86,11 @@ func (v *VNC) GetPort() uint16 {
return v.cfg.LocalPort
}
// OnDisconnect on disconnect message
func (v *VNC) OnDisconnect(id string) {
// TODO
}
// Handle handle shell
func (v *VNC) Handle(c *conn.Conn) {
defer func() {
@@ -110,3 +115,7 @@ func (v *VNC) Handle(c *conn.Conn) {
}
runtime.Assert(svr.ListenAndServe())
}
func (v *VNC) remove(id string) {
v.link = nil
}
+725
View File
@@ -0,0 +1,725 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.0
// protoc v3.21.2
// source: code.proto
package network
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type CodeHeaderValues struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Values []string `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"`
}
func (x *CodeHeaderValues) Reset() {
*x = CodeHeaderValues{}
if protoimpl.UnsafeEnabled {
mi := &file_code_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CodeHeaderValues) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CodeHeaderValues) ProtoMessage() {}
func (x *CodeHeaderValues) ProtoReflect() protoreflect.Message {
mi := &file_code_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CodeHeaderValues.ProtoReflect.Descriptor instead.
func (*CodeHeaderValues) Descriptor() ([]byte, []int) {
return file_code_proto_rawDescGZIP(), []int{0}
}
func (x *CodeHeaderValues) GetValues() []string {
if x != nil {
return x.Values
}
return nil
}
// normal request
type CodeRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
RequestId uint64 `protobuf:"varint,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
Method string `protobuf:"bytes,2,opt,name=method,proto3" json:"method,omitempty"`
Uri string `protobuf:"bytes,3,opt,name=uri,proto3" json:"uri,omitempty"`
Body []byte `protobuf:"bytes,4,opt,name=body,proto3" json:"body,omitempty"`
Header map[string]*CodeHeaderValues `protobuf:"bytes,5,rep,name=header,proto3" json:"header,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
}
func (x *CodeRequest) Reset() {
*x = CodeRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_code_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CodeRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CodeRequest) ProtoMessage() {}
func (x *CodeRequest) ProtoReflect() protoreflect.Message {
mi := &file_code_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CodeRequest.ProtoReflect.Descriptor instead.
func (*CodeRequest) Descriptor() ([]byte, []int) {
return file_code_proto_rawDescGZIP(), []int{1}
}
func (x *CodeRequest) GetRequestId() uint64 {
if x != nil {
return x.RequestId
}
return 0
}
func (x *CodeRequest) GetMethod() string {
if x != nil {
return x.Method
}
return ""
}
func (x *CodeRequest) GetUri() string {
if x != nil {
return x.Uri
}
return ""
}
func (x *CodeRequest) GetBody() []byte {
if x != nil {
return x.Body
}
return nil
}
func (x *CodeRequest) GetHeader() map[string]*CodeHeaderValues {
if x != nil {
return x.Header
}
return nil
}
type CodeResponseHeader struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
RequestId uint64 `protobuf:"varint,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
Code uint32 `protobuf:"varint,2,opt,name=code,proto3" json:"code,omitempty"`
Header map[string]*CodeHeaderValues `protobuf:"bytes,3,rep,name=header,proto3" json:"header,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
}
func (x *CodeResponseHeader) Reset() {
*x = CodeResponseHeader{}
if protoimpl.UnsafeEnabled {
mi := &file_code_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CodeResponseHeader) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CodeResponseHeader) ProtoMessage() {}
func (x *CodeResponseHeader) ProtoReflect() protoreflect.Message {
mi := &file_code_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CodeResponseHeader.ProtoReflect.Descriptor instead.
func (*CodeResponseHeader) Descriptor() ([]byte, []int) {
return file_code_proto_rawDescGZIP(), []int{2}
}
func (x *CodeResponseHeader) GetRequestId() uint64 {
if x != nil {
return x.RequestId
}
return 0
}
func (x *CodeResponseHeader) GetCode() uint32 {
if x != nil {
return x.Code
}
return 0
}
func (x *CodeResponseHeader) GetHeader() map[string]*CodeHeaderValues {
if x != nil {
return x.Header
}
return nil
}
type CodeResponseBody struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
RequestId uint64 `protobuf:"varint,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
Index uint32 `protobuf:"varint,2,opt,name=index,proto3" json:"index,omitempty"`
Mask uint32 `protobuf:"varint,3,opt,name=mask,proto3" json:"mask,omitempty"`
Body []byte `protobuf:"bytes,4,opt,name=body,proto3" json:"body,omitempty"`
}
func (x *CodeResponseBody) Reset() {
*x = CodeResponseBody{}
if protoimpl.UnsafeEnabled {
mi := &file_code_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CodeResponseBody) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CodeResponseBody) ProtoMessage() {}
func (x *CodeResponseBody) ProtoReflect() protoreflect.Message {
mi := &file_code_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CodeResponseBody.ProtoReflect.Descriptor instead.
func (*CodeResponseBody) Descriptor() ([]byte, []int) {
return file_code_proto_rawDescGZIP(), []int{3}
}
func (x *CodeResponseBody) GetRequestId() uint64 {
if x != nil {
return x.RequestId
}
return 0
}
func (x *CodeResponseBody) GetIndex() uint32 {
if x != nil {
return x.Index
}
return 0
}
func (x *CodeResponseBody) GetMask() uint32 {
if x != nil {
return x.Mask
}
return 0
}
func (x *CodeResponseBody) GetBody() []byte {
if x != nil {
return x.Body
}
return nil
}
// websocket
type CodeConnect struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
RequestId uint64 `protobuf:"varint,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
Uri string `protobuf:"bytes,2,opt,name=uri,proto3" json:"uri,omitempty"`
Header map[string]*CodeHeaderValues `protobuf:"bytes,3,rep,name=header,proto3" json:"header,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
}
func (x *CodeConnect) Reset() {
*x = CodeConnect{}
if protoimpl.UnsafeEnabled {
mi := &file_code_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CodeConnect) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CodeConnect) ProtoMessage() {}
func (x *CodeConnect) ProtoReflect() protoreflect.Message {
mi := &file_code_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CodeConnect.ProtoReflect.Descriptor instead.
func (*CodeConnect) Descriptor() ([]byte, []int) {
return file_code_proto_rawDescGZIP(), []int{4}
}
func (x *CodeConnect) GetRequestId() uint64 {
if x != nil {
return x.RequestId
}
return 0
}
func (x *CodeConnect) GetUri() string {
if x != nil {
return x.Uri
}
return ""
}
func (x *CodeConnect) GetHeader() map[string]*CodeHeaderValues {
if x != nil {
return x.Header
}
return nil
}
type CodeConnectResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
RequestId uint64 `protobuf:"varint,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
Ok bool `protobuf:"varint,2,opt,name=ok,proto3" json:"ok,omitempty"`
Msg string `protobuf:"bytes,3,opt,name=msg,proto3" json:"msg,omitempty"`
Header map[string]*CodeHeaderValues `protobuf:"bytes,4,rep,name=header,proto3" json:"header,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
}
func (x *CodeConnectResponse) Reset() {
*x = CodeConnectResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_code_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CodeConnectResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CodeConnectResponse) ProtoMessage() {}
func (x *CodeConnectResponse) ProtoReflect() protoreflect.Message {
mi := &file_code_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CodeConnectResponse.ProtoReflect.Descriptor instead.
func (*CodeConnectResponse) Descriptor() ([]byte, []int) {
return file_code_proto_rawDescGZIP(), []int{5}
}
func (x *CodeConnectResponse) GetRequestId() uint64 {
if x != nil {
return x.RequestId
}
return 0
}
func (x *CodeConnectResponse) GetOk() bool {
if x != nil {
return x.Ok
}
return false
}
func (x *CodeConnectResponse) GetMsg() string {
if x != nil {
return x.Msg
}
return ""
}
func (x *CodeConnectResponse) GetHeader() map[string]*CodeHeaderValues {
if x != nil {
return x.Header
}
return nil
}
type CodeData struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
RequestId uint64 `protobuf:"varint,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"`
Ok bool `protobuf:"varint,2,opt,name=ok,proto3" json:"ok,omitempty"`
Type uint32 `protobuf:"varint,3,opt,name=type,proto3" json:"type,omitempty"`
Data []byte `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"`
}
func (x *CodeData) Reset() {
*x = CodeData{}
if protoimpl.UnsafeEnabled {
mi := &file_code_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CodeData) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CodeData) ProtoMessage() {}
func (x *CodeData) ProtoReflect() protoreflect.Message {
mi := &file_code_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CodeData.ProtoReflect.Descriptor instead.
func (*CodeData) Descriptor() ([]byte, []int) {
return file_code_proto_rawDescGZIP(), []int{6}
}
func (x *CodeData) GetRequestId() uint64 {
if x != nil {
return x.RequestId
}
return 0
}
func (x *CodeData) GetOk() bool {
if x != nil {
return x.Ok
}
return false
}
func (x *CodeData) GetType() uint32 {
if x != nil {
return x.Type
}
return 0
}
func (x *CodeData) GetData() []byte {
if x != nil {
return x.Data
}
return nil
}
var File_code_proto protoreflect.FileDescriptor
var file_code_proto_rawDesc = []byte{
0x0a, 0x0a, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x6e, 0x65,
0x74, 0x77, 0x6f, 0x72, 0x6b, 0x22, 0x2c, 0x0a, 0x12, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x68, 0x65,
0x61, 0x64, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x73, 0x22, 0xfe, 0x01, 0x0a, 0x0c, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x72, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f,
0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20,
0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75,
0x72, 0x69, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x12, 0x0a,
0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64,
0x79, 0x12, 0x39, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x05, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x21, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x63, 0x6f, 0x64, 0x65,
0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x45,
0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x1a, 0x56, 0x0a, 0x0b,
0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b,
0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x31, 0x0a,
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6e,
0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x64,
0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x3a, 0x02, 0x38, 0x01, 0x22, 0xe4, 0x01, 0x0a, 0x14, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x72, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x1d, 0x0a,
0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x04, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04,
0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65,
0x12, 0x41, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x29, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x5f,
0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e,
0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x68, 0x65, 0x61,
0x64, 0x65, 0x72, 0x1a, 0x56, 0x0a, 0x0b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x45, 0x6e, 0x74,
0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x03, 0x6b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x63, 0x6f,
0x64, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73,
0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x71, 0x0a, 0x12, 0x63,
0x6f, 0x64, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x62, 0x6f, 0x64,
0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64,
0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52,
0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x03,
0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x6d, 0x61, 0x73, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f,
0x64, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x22, 0xd2,
0x01, 0x0a, 0x0c, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12,
0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x04, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x10,
0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x69,
0x12, 0x39, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x21, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x5f,
0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x45, 0x6e,
0x74, 0x72, 0x79, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x1a, 0x56, 0x0a, 0x0b, 0x48,
0x65, 0x61, 0x64, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x05,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6e, 0x65,
0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65,
0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a,
0x02, 0x38, 0x01, 0x22, 0xf4, 0x01, 0x0a, 0x15, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x63, 0x6f, 0x6e,
0x6e, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a,
0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x04, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x0e, 0x0a, 0x02,
0x6f, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x12, 0x10, 0x0a, 0x03,
0x6d, 0x73, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x42,
0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a,
0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x63, 0x6f,
0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x48,
0x65, 0x61, 0x64, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64,
0x65, 0x72, 0x1a, 0x56, 0x0a, 0x0b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72,
0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
0x6b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x63, 0x6f, 0x64,
0x65, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52,
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x62, 0x0a, 0x09, 0x63, 0x6f,
0x64, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x72, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x02, 0x20, 0x01,
0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03,
0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61,
0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x42, 0x0c,
0x5a, 0x0a, 0x2e, 0x2f, 0x3b, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
}
var (
file_code_proto_rawDescOnce sync.Once
file_code_proto_rawDescData = file_code_proto_rawDesc
)
func file_code_proto_rawDescGZIP() []byte {
file_code_proto_rawDescOnce.Do(func() {
file_code_proto_rawDescData = protoimpl.X.CompressGZIP(file_code_proto_rawDescData)
})
return file_code_proto_rawDescData
}
var file_code_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
var file_code_proto_goTypes = []interface{}{
(*CodeHeaderValues)(nil), // 0: network.code_header_values
(*CodeRequest)(nil), // 1: network.code_request
(*CodeResponseHeader)(nil), // 2: network.code_response_header
(*CodeResponseBody)(nil), // 3: network.code_response_body
(*CodeConnect)(nil), // 4: network.code_connect
(*CodeConnectResponse)(nil), // 5: network.code_connect_response
(*CodeData)(nil), // 6: network.code_data
nil, // 7: network.code_request.HeaderEntry
nil, // 8: network.code_response_header.HeaderEntry
nil, // 9: network.code_connect.HeaderEntry
nil, // 10: network.code_connect_response.HeaderEntry
}
var file_code_proto_depIdxs = []int32{
7, // 0: network.code_request.header:type_name -> network.code_request.HeaderEntry
8, // 1: network.code_response_header.header:type_name -> network.code_response_header.HeaderEntry
9, // 2: network.code_connect.header:type_name -> network.code_connect.HeaderEntry
10, // 3: network.code_connect_response.header:type_name -> network.code_connect_response.HeaderEntry
0, // 4: network.code_request.HeaderEntry.value:type_name -> network.code_header_values
0, // 5: network.code_response_header.HeaderEntry.value:type_name -> network.code_header_values
0, // 6: network.code_connect.HeaderEntry.value:type_name -> network.code_header_values
0, // 7: network.code_connect_response.HeaderEntry.value:type_name -> network.code_header_values
8, // [8:8] is the sub-list for method output_type
8, // [8:8] is the sub-list for method input_type
8, // [8:8] is the sub-list for extension type_name
8, // [8:8] is the sub-list for extension extendee
0, // [0:8] is the sub-list for field type_name
}
func init() { file_code_proto_init() }
func file_code_proto_init() {
if File_code_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_code_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CodeHeaderValues); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_code_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CodeRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_code_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CodeResponseHeader); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_code_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CodeResponseBody); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_code_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CodeConnect); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_code_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CodeConnectResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_code_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CodeData); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_code_proto_rawDesc,
NumEnums: 0,
NumMessages: 11,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_code_proto_goTypes,
DependencyIndexes: file_code_proto_depIdxs,
MessageInfos: file_code_proto_msgTypes,
}.Build()
File_code_proto = out.File
file_code_proto_rawDesc = nil
file_code_proto_goTypes = nil
file_code_proto_depIdxs = nil
}
+51
View File
@@ -0,0 +1,51 @@
syntax = "proto3";
package network;
option go_package="./;network";
message code_header_values {
repeated string values = 1;
}
// normal request
message code_request {
uint64 request_id = 1;
string method = 2;
string uri = 3;
bytes body = 4;
map<string, code_header_values> header = 5;
}
message code_response_header {
uint64 request_id = 1;
uint32 code = 2;
map<string, code_header_values> header = 3;
}
message code_response_body {
uint64 request_id = 1;
uint32 index = 2;
uint32 mask = 3;
bytes body = 4;
}
// websocket
message code_connect {
uint64 request_id = 1;
string uri = 2;
map<string, code_header_values> header = 3;
}
message code_connect_response {
uint64 request_id = 1;
bool ok = 2;
string msg = 3;
map<string, code_header_values> header = 4;
}
message code_data {
uint64 request_id = 1;
bool ok = 2;
uint32 type = 3;
bytes data = 4;
}
+14 -11
View File
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.27.1
// protoc v3.6.1
// protoc-gen-go v1.28.0
// protoc v3.21.2
// source: connect.proto
package network
@@ -28,6 +28,7 @@ const (
ConnectRequest_shell ConnectRequestType = 2 // shell
ConnectRequest_vnc ConnectRequestType = 3 // vnc
ConnectRequest_bench ConnectRequestType = 4 // benchmark
ConnectRequest_code ConnectRequestType = 5 // code-server
)
// Enum value maps for ConnectRequestType.
@@ -38,6 +39,7 @@ var (
2: "shell",
3: "vnc",
4: "bench",
5: "code",
}
ConnectRequestType_value = map[string]int32{
"tcp": 0,
@@ -45,6 +47,7 @@ var (
"shell": 2,
"vnc": 3,
"bench": 4,
"code": 5,
}
)
@@ -429,7 +432,7 @@ var file_connect_proto_rawDesc = []byte{
0x01, 0x28, 0x0d, 0x52, 0x03, 0x66, 0x70, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x71, 0x75, 0x61, 0x6c,
0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x71, 0x75, 0x61, 0x6c, 0x69,
0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01,
0x28, 0x08, 0x52, 0x06, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x22, 0xaa, 0x02, 0x0a, 0x0f, 0x63,
0x28, 0x08, 0x52, 0x06, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x22, 0xb4, 0x02, 0x0a, 0x0f, 0x63,
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12,
0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
0x6d, 0x65, 0x12, 0x32, 0x0a, 0x05, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
@@ -444,16 +447,16 @@ var file_connect_proto_rawDesc = []byte{
0x06, 0x63, 0x73, 0x68, 0x65, 0x6c, 0x6c, 0x12, 0x2a, 0x0a, 0x04, 0x63, 0x76, 0x6e, 0x63, 0x18,
0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e,
0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x76, 0x6e, 0x63, 0x48, 0x00, 0x52, 0x04, 0x63,
0x76, 0x6e, 0x63, 0x22, 0x37, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x74,
0x76, 0x6e, 0x63, 0x22, 0x41, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x74,
0x63, 0x70, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x75, 0x64, 0x70, 0x10, 0x01, 0x12, 0x09, 0x0a,
0x05, 0x73, 0x68, 0x65, 0x6c, 0x6c, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x76, 0x6e, 0x63, 0x10,
0x03, 0x12, 0x09, 0x0a, 0x05, 0x62, 0x65, 0x6e, 0x63, 0x68, 0x10, 0x04, 0x42, 0x09, 0x0a, 0x07,
0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x34, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x6e, 0x65,
0x63, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f,
0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x12, 0x10, 0x0a, 0x03, 0x6d,
0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x42, 0x0c, 0x5a,
0x0a, 0x2e, 0x2f, 0x3b, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x62, 0x06, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x33,
0x03, 0x12, 0x09, 0x0a, 0x05, 0x62, 0x65, 0x6e, 0x63, 0x68, 0x10, 0x04, 0x12, 0x08, 0x0a, 0x04,
0x63, 0x6f, 0x64, 0x65, 0x10, 0x05, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61,
0x64, 0x22, 0x34, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28,
0x08, 0x52, 0x02, 0x6f, 0x6b, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x2f, 0x3b, 0x6e, 0x65,
0x74, 0x77, 0x6f, 0x72, 0x6b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
+1
View File
@@ -26,6 +26,7 @@ message connect_request {
shell = 2; // shell
vnc = 3; // vnc
bench = 4; // benchmark
code = 5; // code-server
}
string name = 1; // rule name
type _type = 2; // rule type
+2 -2
View File
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.27.1
// protoc v3.6.1
// protoc-gen-go v1.28.0
// protoc v3.21.2
// source: forward.proto
package network
+253 -101
View File
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.27.1
// protoc v3.6.1
// protoc-gen-go v1.28.0
// protoc v3.21.2
// source: msg.proto
package network
@@ -41,6 +41,13 @@ const (
Msg_vnc_cad MsgType = 24 // ctrl+alt+del
Msg_vnc_scroll MsgType = 25
Msg_vnc_clipboard MsgType = 26
// code-server
Msg_code_request MsgType = 30
Msg_code_response_hdr MsgType = 31
Msg_code_response_body MsgType = 32
Msg_code_connect MsgType = 33
Msg_code_connect_response MsgType = 34
Msg_code_data MsgType = 35
)
// Enum value maps for MsgType.
@@ -62,24 +69,36 @@ var (
24: "vnc_cad",
25: "vnc_scroll",
26: "vnc_clipboard",
30: "code_request",
31: "code_response_hdr",
32: "code_response_body",
33: "code_connect",
34: "code_connect_response",
35: "code_data",
}
MsgType_value = map[string]int32{
"unknown": 0,
"handshake": 1,
"keepalive": 2,
"connect_req": 3,
"connect_rep": 4,
"disconnect": 5,
"forward": 6,
"shell_resize": 10,
"shell_data": 11,
"vnc_ctrl": 20,
"vnc_image": 21,
"vnc_mouse": 22,
"vnc_keyboard": 23,
"vnc_cad": 24,
"vnc_scroll": 25,
"vnc_clipboard": 26,
"unknown": 0,
"handshake": 1,
"keepalive": 2,
"connect_req": 3,
"connect_rep": 4,
"disconnect": 5,
"forward": 6,
"shell_resize": 10,
"shell_data": 11,
"vnc_ctrl": 20,
"vnc_image": 21,
"vnc_mouse": 22,
"vnc_keyboard": 23,
"vnc_cad": 24,
"vnc_scroll": 25,
"vnc_clipboard": 26,
"code_request": 30,
"code_response_hdr": 31,
"code_response_body": 32,
"code_connect": 33,
"code_connect_response": 34,
"code_data": 35,
}
)
@@ -179,6 +198,12 @@ type Msg struct {
// *Msg_Vkbd
// *Msg_Vscroll
// *Msg_Vclipboard
// *Msg_Csreq
// *Msg_CsrepHdr
// *Msg_CsrepBody
// *Msg_Csconn
// *Msg_CsconnRep
// *Msg_Csdata
Payload isMsg_Payload `protobuf_oneof:"payload"`
}
@@ -333,6 +358,48 @@ func (x *Msg) GetVclipboard() *VncClipboard {
return nil
}
func (x *Msg) GetCsreq() *CodeRequest {
if x, ok := x.GetPayload().(*Msg_Csreq); ok {
return x.Csreq
}
return nil
}
func (x *Msg) GetCsrepHdr() *CodeResponseHeader {
if x, ok := x.GetPayload().(*Msg_CsrepHdr); ok {
return x.CsrepHdr
}
return nil
}
func (x *Msg) GetCsrepBody() *CodeResponseBody {
if x, ok := x.GetPayload().(*Msg_CsrepBody); ok {
return x.CsrepBody
}
return nil
}
func (x *Msg) GetCsconn() *CodeConnect {
if x, ok := x.GetPayload().(*Msg_Csconn); ok {
return x.Csconn
}
return nil
}
func (x *Msg) GetCsconnRep() *CodeConnectResponse {
if x, ok := x.GetPayload().(*Msg_CsconnRep); ok {
return x.CsconnRep
}
return nil
}
func (x *Msg) GetCsdata() *CodeData {
if x, ok := x.GetPayload().(*Msg_Csdata); ok {
return x.Csdata
}
return nil
}
type isMsg_Payload interface {
isMsg_Payload()
}
@@ -387,6 +454,31 @@ type Msg_Vclipboard struct {
Vclipboard *VncClipboard `protobuf:"bytes,35,opt,name=vclipboard,proto3,oneof"`
}
type Msg_Csreq struct {
// code-server
Csreq *CodeRequest `protobuf:"bytes,40,opt,name=csreq,proto3,oneof"`
}
type Msg_CsrepHdr struct {
CsrepHdr *CodeResponseHeader `protobuf:"bytes,41,opt,name=csrep_hdr,json=csrepHdr,proto3,oneof"`
}
type Msg_CsrepBody struct {
CsrepBody *CodeResponseBody `protobuf:"bytes,42,opt,name=csrep_body,json=csrepBody,proto3,oneof"`
}
type Msg_Csconn struct {
Csconn *CodeConnect `protobuf:"bytes,43,opt,name=csconn,proto3,oneof"`
}
type Msg_CsconnRep struct {
CsconnRep *CodeConnectResponse `protobuf:"bytes,44,opt,name=csconn_rep,json=csconnRep,proto3,oneof"`
}
type Msg_Csdata struct {
Csdata *CodeData `protobuf:"bytes,45,opt,name=csdata,proto3,oneof"`
}
func (*Msg_Hsp) isMsg_Payload() {}
func (*Msg_Creq) isMsg_Payload() {}
@@ -411,6 +503,18 @@ func (*Msg_Vscroll) isMsg_Payload() {}
func (*Msg_Vclipboard) isMsg_Payload() {}
func (*Msg_Csreq) isMsg_Payload() {}
func (*Msg_CsrepHdr) isMsg_Payload() {}
func (*Msg_CsrepBody) isMsg_Payload() {}
func (*Msg_Csconn) isMsg_Payload() {}
func (*Msg_CsconnRep) isMsg_Payload() {}
func (*Msg_Csdata) isMsg_Payload() {}
var File_msg_proto protoreflect.FileDescriptor
var file_msg_proto_rawDesc = []byte{
@@ -418,70 +522,99 @@ var file_msg_proto_rawDesc = []byte{
0x77, 0x6f, 0x72, 0x6b, 0x1a, 0x0d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x1a, 0x0d, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x1a, 0x0b, 0x73, 0x68, 0x65, 0x6c, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
0x09, 0x76, 0x6e, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x25, 0x0a, 0x11, 0x68, 0x61,
0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12,
0x10, 0x0a, 0x03, 0x65, 0x6e, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x65, 0x6e,
0x63, 0x22, 0xad, 0x07, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x26, 0x0a, 0x05, 0x5f, 0x74, 0x79,
0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f,
0x72, 0x6b, 0x2e, 0x6d, 0x73, 0x67, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x52, 0x04, 0x54, 0x79, 0x70,
0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28,
0x09, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x17, 0x0a, 0x07, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x69, 0x64,
0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6c, 0x69, 0x6e, 0x6b, 0x49, 0x64, 0x12, 0x2e,
0x0a, 0x03, 0x68, 0x73, 0x70, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6e, 0x65,
0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x68, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x5f,
0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x48, 0x00, 0x52, 0x03, 0x68, 0x73, 0x70, 0x12, 0x2e,
0x0a, 0x04, 0x63, 0x72, 0x65, 0x71, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6e,
0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x72,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x04, 0x63, 0x72, 0x65, 0x71, 0x12, 0x2f,
0x0a, 0x04, 0x63, 0x72, 0x65, 0x70, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6e,
0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x72,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x04, 0x63, 0x72, 0x65, 0x70, 0x12,
0x24, 0x0a, 0x05, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d,
0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52,
0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x31, 0x0a, 0x07, 0x73, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65,
0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
0x2e, 0x73, 0x68, 0x65, 0x6c, 0x6c, 0x5f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x48, 0x00, 0x52,
0x07, 0x73, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x2b, 0x0a, 0x05, 0x73, 0x64, 0x61, 0x74,
0x61, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72,
0x6b, 0x2e, 0x73, 0x68, 0x65, 0x6c, 0x6c, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52, 0x05,
0x73, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x63, 0x74, 0x72, 0x6c, 0x18, 0x1e,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x76,
0x6e, 0x63, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x48, 0x00, 0x52, 0x05, 0x76, 0x63,
0x74, 0x72, 0x6c, 0x12, 0x28, 0x0a, 0x04, 0x76, 0x69, 0x6d, 0x67, 0x18, 0x1f, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x12, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x76, 0x6e, 0x63, 0x5f,
0x69, 0x6d, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x04, 0x76, 0x69, 0x6d, 0x67, 0x12, 0x2c, 0x0a,
0x06, 0x76, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e,
0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x76, 0x6e, 0x63, 0x5f, 0x6d, 0x6f, 0x75, 0x73,
0x65, 0x48, 0x00, 0x52, 0x06, 0x76, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x04, 0x76,
0x6b, 0x62, 0x64, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6e, 0x65, 0x74, 0x77,
0x6f, 0x72, 0x6b, 0x2e, 0x76, 0x6e, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x62, 0x6f, 0x61, 0x72, 0x64,
0x48, 0x00, 0x52, 0x04, 0x76, 0x6b, 0x62, 0x64, 0x12, 0x2f, 0x0a, 0x07, 0x76, 0x73, 0x63, 0x72,
0x6f, 0x6c, 0x6c, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6e, 0x65, 0x74, 0x77,
0x6f, 0x72, 0x6b, 0x2e, 0x76, 0x6e, 0x63, 0x5f, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x48, 0x00,
0x52, 0x07, 0x76, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x12, 0x38, 0x0a, 0x0a, 0x76, 0x63, 0x6c,
0x69, 0x70, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x18, 0x23, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e,
0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x76, 0x6e, 0x63, 0x5f, 0x63, 0x6c, 0x69, 0x70,
0x62, 0x6f, 0x61, 0x72, 0x64, 0x48, 0x00, 0x52, 0x0a, 0x76, 0x63, 0x6c, 0x69, 0x70, 0x62, 0x6f,
0x61, 0x72, 0x64, 0x22, 0x80, 0x02, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07,
0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x68, 0x61, 0x6e,
0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70,
0x61, 0x6c, 0x69, 0x76, 0x65, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x6e, 0x65,
0x63, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x6e,
0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x10, 0x04, 0x12, 0x0e, 0x0a, 0x0a, 0x64, 0x69, 0x73,
0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x10, 0x05, 0x12, 0x0b, 0x0a, 0x07, 0x66, 0x6f, 0x72,
0x77, 0x61, 0x72, 0x64, 0x10, 0x06, 0x12, 0x10, 0x0a, 0x0c, 0x73, 0x68, 0x65, 0x6c, 0x6c, 0x5f,
0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x10, 0x0a, 0x12, 0x0e, 0x0a, 0x0a, 0x73, 0x68, 0x65, 0x6c,
0x6c, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x10, 0x0b, 0x12, 0x0c, 0x0a, 0x08, 0x76, 0x6e, 0x63, 0x5f,
0x63, 0x74, 0x72, 0x6c, 0x10, 0x14, 0x12, 0x0d, 0x0a, 0x09, 0x76, 0x6e, 0x63, 0x5f, 0x69, 0x6d,
0x61, 0x67, 0x65, 0x10, 0x15, 0x12, 0x0d, 0x0a, 0x09, 0x76, 0x6e, 0x63, 0x5f, 0x6d, 0x6f, 0x75,
0x73, 0x65, 0x10, 0x16, 0x12, 0x10, 0x0a, 0x0c, 0x76, 0x6e, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x62,
0x6f, 0x61, 0x72, 0x64, 0x10, 0x17, 0x12, 0x0b, 0x0a, 0x07, 0x76, 0x6e, 0x63, 0x5f, 0x63, 0x61,
0x64, 0x10, 0x18, 0x12, 0x0e, 0x0a, 0x0a, 0x76, 0x6e, 0x63, 0x5f, 0x73, 0x63, 0x72, 0x6f, 0x6c,
0x6c, 0x10, 0x19, 0x12, 0x11, 0x0a, 0x0d, 0x76, 0x6e, 0x63, 0x5f, 0x63, 0x6c, 0x69, 0x70, 0x62,
0x6f, 0x61, 0x72, 0x64, 0x10, 0x1a, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61,
0x64, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x2f, 0x3b, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x09, 0x76, 0x6e, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0a, 0x63, 0x6f, 0x64, 0x65,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x25, 0x0a, 0x11, 0x68, 0x61, 0x6e, 0x64, 0x73, 0x68,
0x61, 0x6b, 0x65, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x65,
0x6e, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x65, 0x6e, 0x63, 0x22, 0xf5, 0x0a,
0x0a, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x26, 0x0a, 0x05, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x6d,
0x73, 0x67, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a,
0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f,
0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x74,
0x6f, 0x12, 0x17, 0x0a, 0x07, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01,
0x28, 0x09, 0x52, 0x06, 0x6c, 0x69, 0x6e, 0x6b, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x03, 0x68, 0x73,
0x70, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72,
0x6b, 0x2e, 0x68, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x5f, 0x70, 0x61, 0x79, 0x6c,
0x6f, 0x61, 0x64, 0x48, 0x00, 0x52, 0x03, 0x68, 0x73, 0x70, 0x12, 0x2e, 0x0a, 0x04, 0x63, 0x72,
0x65, 0x71, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f,
0x72, 0x6b, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x48, 0x00, 0x52, 0x04, 0x63, 0x72, 0x65, 0x71, 0x12, 0x2f, 0x0a, 0x04, 0x63, 0x72,
0x65, 0x70, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f,
0x72, 0x6b, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x04, 0x63, 0x72, 0x65, 0x70, 0x12, 0x24, 0x0a, 0x05, 0x5f,
0x64, 0x61, 0x74, 0x61, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6e, 0x65, 0x74,
0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52, 0x04, 0x44, 0x61, 0x74,
0x61, 0x12, 0x31, 0x0a, 0x07, 0x73, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x14, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x73, 0x68, 0x65,
0x6c, 0x6c, 0x5f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x48, 0x00, 0x52, 0x07, 0x73, 0x72, 0x65,
0x73, 0x69, 0x7a, 0x65, 0x12, 0x2b, 0x0a, 0x05, 0x73, 0x64, 0x61, 0x74, 0x61, 0x18, 0x15, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x73, 0x68,
0x65, 0x6c, 0x6c, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52, 0x05, 0x73, 0x64, 0x61, 0x74,
0x61, 0x12, 0x2c, 0x0a, 0x05, 0x76, 0x63, 0x74, 0x72, 0x6c, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x14, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x76, 0x6e, 0x63, 0x5f, 0x63,
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x48, 0x00, 0x52, 0x05, 0x76, 0x63, 0x74, 0x72, 0x6c, 0x12,
0x28, 0x0a, 0x04, 0x76, 0x69, 0x6d, 0x67, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e,
0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x76, 0x6e, 0x63, 0x5f, 0x69, 0x6d, 0x61, 0x67,
0x65, 0x48, 0x00, 0x52, 0x04, 0x76, 0x69, 0x6d, 0x67, 0x12, 0x2c, 0x0a, 0x06, 0x76, 0x6d, 0x6f,
0x75, 0x73, 0x65, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6e, 0x65, 0x74, 0x77,
0x6f, 0x72, 0x6b, 0x2e, 0x76, 0x6e, 0x63, 0x5f, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x48, 0x00, 0x52,
0x06, 0x76, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x04, 0x76, 0x6b, 0x62, 0x64, 0x18,
0x21, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e,
0x76, 0x6e, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x48, 0x00, 0x52, 0x04,
0x76, 0x6b, 0x62, 0x64, 0x12, 0x2f, 0x0a, 0x07, 0x76, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x18,
0x22, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e,
0x76, 0x6e, 0x63, 0x5f, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x48, 0x00, 0x52, 0x07, 0x76, 0x73,
0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x12, 0x38, 0x0a, 0x0a, 0x76, 0x63, 0x6c, 0x69, 0x70, 0x62, 0x6f,
0x61, 0x72, 0x64, 0x18, 0x23, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6e, 0x65, 0x74, 0x77,
0x6f, 0x72, 0x6b, 0x2e, 0x76, 0x6e, 0x63, 0x5f, 0x63, 0x6c, 0x69, 0x70, 0x62, 0x6f, 0x61, 0x72,
0x64, 0x48, 0x00, 0x52, 0x0a, 0x76, 0x63, 0x6c, 0x69, 0x70, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x12,
0x2d, 0x0a, 0x05, 0x63, 0x73, 0x72, 0x65, 0x71, 0x18, 0x28, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15,
0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x72, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x05, 0x63, 0x73, 0x72, 0x65, 0x71, 0x12, 0x3c,
0x0a, 0x09, 0x63, 0x73, 0x72, 0x65, 0x70, 0x5f, 0x68, 0x64, 0x72, 0x18, 0x29, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x1d, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x63, 0x6f, 0x64, 0x65,
0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72,
0x48, 0x00, 0x52, 0x08, 0x63, 0x73, 0x72, 0x65, 0x70, 0x48, 0x64, 0x72, 0x12, 0x3c, 0x0a, 0x0a,
0x63, 0x73, 0x72, 0x65, 0x70, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x2a, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x1b, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x5f,
0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x48, 0x00, 0x52,
0x09, 0x63, 0x73, 0x72, 0x65, 0x70, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x73,
0x63, 0x6f, 0x6e, 0x6e, 0x18, 0x2b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6e, 0x65, 0x74,
0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
0x74, 0x48, 0x00, 0x52, 0x06, 0x63, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x12, 0x3f, 0x0a, 0x0a, 0x63,
0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x5f, 0x72, 0x65, 0x70, 0x18, 0x2c, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x1e, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x63,
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48,
0x00, 0x52, 0x09, 0x63, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x52, 0x65, 0x70, 0x12, 0x2c, 0x0a, 0x06,
0x63, 0x73, 0x64, 0x61, 0x74, 0x61, 0x18, 0x2d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6e,
0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61,
0x48, 0x00, 0x52, 0x06, 0x63, 0x73, 0x64, 0x61, 0x74, 0x61, 0x22, 0xfd, 0x02, 0x0a, 0x04, 0x74,
0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00,
0x12, 0x0d, 0x0a, 0x09, 0x68, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x10, 0x01, 0x12,
0x0d, 0x0a, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x10, 0x02, 0x12, 0x0f,
0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x10, 0x03, 0x12,
0x0f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x10, 0x04,
0x12, 0x0e, 0x0a, 0x0a, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x10, 0x05,
0x12, 0x0b, 0x0a, 0x07, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x10, 0x06, 0x12, 0x10, 0x0a,
0x0c, 0x73, 0x68, 0x65, 0x6c, 0x6c, 0x5f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x10, 0x0a, 0x12,
0x0e, 0x0a, 0x0a, 0x73, 0x68, 0x65, 0x6c, 0x6c, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x10, 0x0b, 0x12,
0x0c, 0x0a, 0x08, 0x76, 0x6e, 0x63, 0x5f, 0x63, 0x74, 0x72, 0x6c, 0x10, 0x14, 0x12, 0x0d, 0x0a,
0x09, 0x76, 0x6e, 0x63, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x10, 0x15, 0x12, 0x0d, 0x0a, 0x09,
0x76, 0x6e, 0x63, 0x5f, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x10, 0x16, 0x12, 0x10, 0x0a, 0x0c, 0x76,
0x6e, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x10, 0x17, 0x12, 0x0b, 0x0a,
0x07, 0x76, 0x6e, 0x63, 0x5f, 0x63, 0x61, 0x64, 0x10, 0x18, 0x12, 0x0e, 0x0a, 0x0a, 0x76, 0x6e,
0x63, 0x5f, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x10, 0x19, 0x12, 0x11, 0x0a, 0x0d, 0x76, 0x6e,
0x63, 0x5f, 0x63, 0x6c, 0x69, 0x70, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x10, 0x1a, 0x12, 0x10, 0x0a,
0x0c, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0x1e, 0x12,
0x15, 0x0a, 0x11, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x5f, 0x68, 0x64, 0x72, 0x10, 0x1f, 0x12, 0x16, 0x0a, 0x12, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x72,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x10, 0x20, 0x12, 0x10,
0x0a, 0x0c, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x10, 0x21,
0x12, 0x19, 0x0a, 0x15, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x10, 0x22, 0x12, 0x0d, 0x0a, 0x09, 0x63,
0x6f, 0x64, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x10, 0x23, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61,
0x79, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x2f, 0x3b, 0x6e, 0x65, 0x74, 0x77,
0x6f, 0x72, 0x6b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -499,20 +632,26 @@ func file_msg_proto_rawDescGZIP() []byte {
var file_msg_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_msg_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_msg_proto_goTypes = []interface{}{
(MsgType)(0), // 0: network.msg.type
(*HandshakePayload)(nil), // 1: network.handshake_payload
(*Msg)(nil), // 2: network.msg
(*ConnectRequest)(nil), // 3: network.connect_request
(*ConnectResponse)(nil), // 4: network.connect_response
(*Data)(nil), // 5: network.data
(*ShellResize)(nil), // 6: network.shell_resize
(*ShellData)(nil), // 7: network.shell_data
(*VncControl)(nil), // 8: network.vnc_control
(*VncImage)(nil), // 9: network.vnc_image
(*VncMouse)(nil), // 10: network.vnc_mouse
(*VncKeyboard)(nil), // 11: network.vnc_keyboard
(*VncScroll)(nil), // 12: network.vnc_scroll
(*VncClipboard)(nil), // 13: network.vnc_clipboard
(MsgType)(0), // 0: network.msg.type
(*HandshakePayload)(nil), // 1: network.handshake_payload
(*Msg)(nil), // 2: network.msg
(*ConnectRequest)(nil), // 3: network.connect_request
(*ConnectResponse)(nil), // 4: network.connect_response
(*Data)(nil), // 5: network.data
(*ShellResize)(nil), // 6: network.shell_resize
(*ShellData)(nil), // 7: network.shell_data
(*VncControl)(nil), // 8: network.vnc_control
(*VncImage)(nil), // 9: network.vnc_image
(*VncMouse)(nil), // 10: network.vnc_mouse
(*VncKeyboard)(nil), // 11: network.vnc_keyboard
(*VncScroll)(nil), // 12: network.vnc_scroll
(*VncClipboard)(nil), // 13: network.vnc_clipboard
(*CodeRequest)(nil), // 14: network.code_request
(*CodeResponseHeader)(nil), // 15: network.code_response_header
(*CodeResponseBody)(nil), // 16: network.code_response_body
(*CodeConnect)(nil), // 17: network.code_connect
(*CodeConnectResponse)(nil), // 18: network.code_connect_response
(*CodeData)(nil), // 19: network.code_data
}
var file_msg_proto_depIdxs = []int32{
0, // 0: network.msg._type:type_name -> network.msg.type
@@ -528,11 +667,17 @@ var file_msg_proto_depIdxs = []int32{
11, // 10: network.msg.vkbd:type_name -> network.vnc_keyboard
12, // 11: network.msg.vscroll:type_name -> network.vnc_scroll
13, // 12: network.msg.vclipboard:type_name -> network.vnc_clipboard
13, // [13:13] is the sub-list for method output_type
13, // [13:13] is the sub-list for method input_type
13, // [13:13] is the sub-list for extension type_name
13, // [13:13] is the sub-list for extension extendee
0, // [0:13] is the sub-list for field type_name
14, // 13: network.msg.csreq:type_name -> network.code_request
15, // 14: network.msg.csrep_hdr:type_name -> network.code_response_header
16, // 15: network.msg.csrep_body:type_name -> network.code_response_body
17, // 16: network.msg.csconn:type_name -> network.code_connect
18, // 17: network.msg.csconn_rep:type_name -> network.code_connect_response
19, // 18: network.msg.csdata:type_name -> network.code_data
19, // [19:19] is the sub-list for method output_type
19, // [19:19] is the sub-list for method input_type
19, // [19:19] is the sub-list for extension type_name
19, // [19:19] is the sub-list for extension extendee
0, // [0:19] is the sub-list for field type_name
}
func init() { file_msg_proto_init() }
@@ -544,6 +689,7 @@ func file_msg_proto_init() {
file_forward_proto_init()
file_shell_proto_init()
file_vnc_proto_init()
file_code_proto_init()
if !protoimpl.UnsafeEnabled {
file_msg_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HandshakePayload); i {
@@ -583,6 +729,12 @@ func file_msg_proto_init() {
(*Msg_Vkbd)(nil),
(*Msg_Vscroll)(nil),
(*Msg_Vclipboard)(nil),
(*Msg_Csreq)(nil),
(*Msg_CsrepHdr)(nil),
(*Msg_CsrepBody)(nil),
(*Msg_Csconn)(nil),
(*Msg_CsconnRep)(nil),
(*Msg_Csdata)(nil),
}
type x struct{}
out := protoimpl.TypeBuilder{
+15
View File
@@ -7,6 +7,7 @@ import "connect.proto";
import "forward.proto";
import "shell.proto";
import "vnc.proto";
import "code.proto";
message handshake_payload {
bytes enc = 1;
@@ -32,6 +33,13 @@ message msg {
vnc_cad = 24; // ctrl+alt+del
vnc_scroll = 25;
vnc_clipboard = 26;
// code-server
code_request = 30;
code_response_hdr = 31;
code_response_body = 32;
code_connect = 33;
code_connect_response = 34;
code_data = 35;
}
type _type = 1;
string from = 2;
@@ -52,5 +60,12 @@ message msg {
vnc_keyboard vkbd = 33;
vnc_scroll vscroll = 34;
vnc_clipboard vclipboard = 35;
// code-server
code_request csreq = 40;
code_response_header csrep_hdr = 41;
code_response_body csrep_body = 42;
code_connect csconn = 43;
code_connect_response csconn_rep = 44;
code_data csdata = 45;
}
}
+2 -2
View File
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.27.1
// protoc v3.6.1
// protoc-gen-go v1.28.0
// protoc v3.21.2
// source: shell.proto
package network
+2 -2
View File
@@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.27.1
// protoc v3.6.1
// protoc-gen-go v1.28.0
// protoc v3.21.2
// source: vnc.proto
package network
+1 -1
View File
@@ -123,7 +123,7 @@ func main() {
switch *act {
case "install":
runtime.Assert(sv.Install())
utils.BuildLogDir(cfg.LogDir, *user)
utils.BuildDir(cfg.LogDir, *user)
case "uninstall":
runtime.Assert(sv.Uninstall())
default:
+2 -2
View File
@@ -8,8 +8,8 @@ import (
"github.com/lwch/runtime"
)
// BuildLogDir mkdir for log and chown
func BuildLogDir(dir, u string) {
// BuildDir mkdir and chown
func BuildDir(dir, u string) {
runtime.Assert(os.MkdirAll(dir, 0755))
if len(u) > 0 {
us, err := user.Lookup(u)
+2 -1
View File
@@ -5,4 +5,5 @@ link:
log:
dir: ./logs # 路径,相对于可执行文件所在目录的相对路径
size: 50M # 单个文件大小
rotate: 7 # 保留数量
rotate: 7 # 保留数量
codedir: ./code # code-server配置保存路径
+10
View File
@@ -0,0 +1,10 @@
# 1. 需先在受控端主机上安装code-server并添加到PATH环境变量
# 下载地址:https://github.com/coder/code-server/releases
# 2. code-server默认使用OpenVSX扩展商店
# 若需切换到微软扩展商店可通过配置系统环境变量EXTENSIONS_GALLERY进行切换
# 详见说明:https://github.com/coder/code-server/blob/10f57bac65f9aa5938df4e495da39c608fbf7798/docs/FAQ.md#how-do-i-use-my-own-extensions-marketplace
- name: code-server # 链路名称
target: remote # 目标客户端ID
type: code-server # code-server
local_addr: 0.0.0.0 # 本地监听地址
local_port: 8000 # 本地监听端口号
+1
View File
@@ -1,3 +1,4 @@
# 目前不支持arm架构的windows和linux操作系统
- name: vnc # 链路名称
target: remote # 目标客户端ID
type: vnc # web vnc
+1 -1
View File
@@ -1,6 +1,6 @@
ARG APT_MIRROR=mirrors.ustc.edu.cn
ARG LIBPNG_VERSION=1.6.37
ARG GO_VERSION=1.18.3
ARG GO_VERSION=1.18.4
ARG GO_PROXY=https://goproxy.cn,direct
FROM lwch/darwin-crosscompiler:11.3
+2 -2
View File
@@ -21,10 +21,10 @@ go run contrib/bindata/main.go -pkg shell -o code/client/rule/shell/assets.go \
-prefix html/shell "$@" html/shell/...
go run contrib/bindata/main.go -pkg vnc -o code/client/rule/vnc/assets.go \
-prefix html/vnc "$@" html/vnc/...
go run contrib/bindata/main.go -pkg code -o code/client/rule/code/assets.go \
-prefix html/code "$@" html/code/...
go run contrib/bindata/main.go -pkg dashboard -o code/client/dashboard/assets.go \
-prefix html/dashboard "$@" html/dashboard/...
go build -ldflags "$LDFLAGS" -o bin/np-svr code/server/*.go
# CC=x86_64-w64-mingw32-gcc \
# CXX=x86_64-w64-mingw32-g++ \
go build -ldflags "$LDFLAGS" -tags "$TAGS" -o bin/np-cli code/client/*.go
+9
View File
@@ -136,6 +136,15 @@ func bindata() {
cmd.Stderr = os.Stderr
runtime.Assert(cmd.Run())
cmd = exec.Command("go", "run", "contrib/bindata/main.go",
"-pkg", "code",
"-o", "code/client/rule/code/assets.go",
"-prefix", "html/code",
"html/code/...")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
runtime.Assert(cmd.Run())
cmd = exec.Command("go", "run", "contrib/bindata/main.go",
"-pkg", "dashboard",
"-o", "code/client/dashboard/assets.go",
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

+3 -2
View File
@@ -13,10 +13,11 @@ require (
github.com/lwch/rdesktop v1.1.1
github.com/lwch/runtime v0.0.0-20190520054850-8c97e19e0c6d
github.com/lwch/yaml v0.0.0-20220711084242-14c4f5845abe
golang.org/x/image v0.0.0-20220722155232-062f8c9fd539 // indirect
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10
golang.org/x/text v0.3.7
golang.org/x/tools v0.1.11 // indirect
golang.org/x/tools v0.1.12 // indirect
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect
google.golang.org/protobuf v1.28.0
)
+12 -5
View File
@@ -24,11 +24,13 @@ github.com/lwch/runtime v0.0.0-20190520054850-8c97e19e0c6d/go.mod h1:uEt0zu1MDC7
github.com/lwch/yaml v0.0.0-20220711084242-14c4f5845abe h1:PJ1zNqqiHW2q480seGnr9G8/Oke/JxF4HscxEuV+a6Y=
github.com/lwch/yaml v0.0.0-20220711084242-14c4f5845abe/go.mod h1:n4iNSR61Lth9WtFYMYdw/eo92v/AZpz/ml9FuYJ0vd0=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/image v0.0.0-20220617043117-41969df76e82 h1:KpZB5pUSBvrHltNEdK/tw0xlPeD13M6M6aGP32gKqiw=
golang.org/x/image v0.0.0-20220617043117-41969df76e82/go.mod h1:doUCurBvlfPMKfmIpRIywoHmhN3VyhnoFDbvIEWF4hY=
golang.org/x/image v0.0.0-20220722155232-062f8c9fd539 h1:/eM0PCrQI2xd471rI+snWuu251/+/jpBpZqir2mPdnU=
golang.org/x/image v0.0.0-20220722155232-062f8c9fd539/go.mod h1:doUCurBvlfPMKfmIpRIywoHmhN3VyhnoFDbvIEWF4hY=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
@@ -40,8 +42,10 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -49,9 +53,12 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d h1:/m5NbqQelATgoSPVC2Z23sR4kVNokFwDDyWh/3rGY+I=
golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@@ -63,8 +70,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
golang.org/x/tools v0.1.11 h1:loJ25fNOEhSXfHrpoGj91eCUThwdNX6u24rO1xnNteY=
golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4=
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+1
View File
@@ -0,0 +1 @@
../js/common.js
+1
View File
@@ -0,0 +1 @@
../fontawesome-free-5.15.4
+41
View File
@@ -0,0 +1,41 @@
html {
height: 100%;
}
body {
margin: 0 !important;
padding: 0 !important;
height: 100% !important;
}
.container-fluid {
height: 100%;
overflow-y: hidden;
}
#header {
padding-top: 4px;
}
#fullscreen {
float: right;
margin-right: 5px;
}
#info {
float: right;
margin-right: 5px;
}
#closed {
color: red;
float: right;
margin-right: 5px;
font-weight: bold;
}
label, span {
line-height: 38px;
}
#fullscreen {
cursor: pointer;
font-size: 38px;
}
#code {
width: 100%;
height: calc(100% - 42px);
border: none;
}
+25
View File
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>code - [{{.Name}}]</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="/jquery/jquery-3.6.0.min.js"></script>
<script src="/fontawesome/js/all.min.js"></script>
<link rel="stylesheet" href="/index.css" />
<script src="common.js"></script>
<script src="/index.js"></script>
</head>
<body>
<div class="container-fluid">
<div id="header">
<i id="fullscreen" class="fas fa-expand"></i>
<span id="info">send: 0 B/s, recv: 0 B/s</span>
<span id="closed" style="display: none;">连接已断开</span>
</div>
<!-- header -->
<iframe id="code"></iframe>
</div>
</body>
</html>
+47
View File
@@ -0,0 +1,47 @@
var page = {
init: function() {
$('#fullscreen').click(page.fullscreen);
$('#code').on('load', function() {
var qry = $('#code')[0].contentWindow.location.search;
var params = new URLSearchParams(qry);
page.id = params.get('natpass_connection_id');
});
page.connect();
setInterval(page.update_info, page.secs*1000);
},
connect: function() {
$.get('/new', function(ret) {
page.name = ret;
$('#code').attr('src', `/forward/${page.name}/`);
});
},
update_info: function() {
if (!page.id) {
return;
}
$.get('/info?id='+page.id, function(ret) {
var send_bytes = ret.send_bytes - page.send;
var recv_bytes = ret.recv_bytes - page.recv;
if (send_bytes < 0) {
send_bytes = 0;
}
if (recv_bytes < 0) {
recv_bytes = 0;
}
page.send = ret.send_bytes;
page.recv = ret.recv_bytes;
var str = 'send: '+humanize.bytes(send_bytes/page.secs)+'/s, '+
'recv: '+humanize.bytes(recv_bytes/page.secs)+'/s';
$('#info').text(str);
});
},
fullscreen: function() {
$('#code')[0].requestFullscreen();
},
id: '',
name: '',
secs: 2,
send: 0,
recv: 0
};
$(document).ready(page.init);
+1
View File
@@ -0,0 +1 @@
../jquery
+1 -5
View File
@@ -36,13 +36,9 @@ var page = {
});
var op = '';
switch (rule.type) {
case 'reverse':
op = `
<a href="http://${location.hostname}:${rule.port}" target="_blank">http</a>
<a href="https://${location.hostname}:${rule.port}" target="_blank">https</a>`;
break;
case 'shell':
case 'vnc':
case 'code-server':
op = `<a href="http://${location.host}/terminal.html?name=${rule.name}" target="_blank">连接</a>`;
break;
}
+2 -1
View File
@@ -15,7 +15,8 @@ var page = {
$('#terms').empty();
$.each(ret, function(_, rule) {
if (rule.type != 'shell' &&
rule.type != 'vnc') {
rule.type != 'vnc' &&
rule.type != 'code-server') {
return;
}
$('#terms').append($(`<option value="${rule.port}">${rule.name}</option>`));
+146
View File
@@ -0,0 +1,146 @@
package main
import (
"fmt"
"io"
"net"
"net/http"
"os"
"os/exec"
"path/filepath"
"strings"
"sync"
"time"
"github.com/gorilla/websocket"
"github.com/lwch/runtime"
)
var cli = &http.Client{
Transport: &http.Transport{
Dial: func(network, addr string) (net.Conn, error) {
return net.Dial("unix", "./code-server/code-server.sock")
},
},
}
var upgrader = websocket.Upgrader{}
var dialer = websocket.Dialer{
NetDial: func(network, addr string) (net.Conn, error) {
return net.Dial("unix", "./code-server/code-server.sock")
},
}
func main() {
dir := "/home/lwch/src/natpass/code-server"
exec := exec.Command("code-server", "--disable-update-check",
"--auth", "none",
"--socket", filepath.Join(dir, "code-server.sock"),
"--user-data-dir", filepath.Join(dir, "data"),
"--extensions-dir", filepath.Join(dir, "extensions"), ".")
exec.Stdout = os.Stdout
exec.Stderr = os.Stderr
runtime.Assert(exec.Start())
time.Sleep(time.Second)
go exec.Wait()
conn, err := net.Dial("unix", "./code-server/code-server.sock")
runtime.Assert(err)
conn.Close()
http.HandleFunc("/", next)
http.ListenAndServe(":8001", nil)
}
func normal(w http.ResponseWriter, r *http.Request) {
u := r.URL
u.Scheme = "http"
u.Host = "unix"
req, err := http.NewRequest(r.Method, u.String(), r.Body)
runtime.Assert(err)
for key, values := range r.Header {
for _, v := range values {
req.Header.Add(key, v)
}
}
rep, err := cli.Do(req)
runtime.Assert(err)
defer rep.Body.Close()
for key, values := range rep.Header {
for _, v := range values {
w.Header().Add(key, v)
}
}
w.WriteHeader(rep.StatusCode)
_, err = io.Copy(w, rep.Body)
runtime.Assert(err)
}
func ws(w http.ResponseWriter, r *http.Request) {
u := r.URL
u.Scheme = "ws"
u.Host = "unix"
hdr := make(http.Header)
for key, values := range r.Header {
if strings.HasPrefix(key, "Sec-") {
continue
}
for _, value := range values {
hdr.Add(key, value)
}
}
hdr.Del("Connection")
hdr.Del("Upgrade")
remote, resp, err := dialer.Dial(u.String(), hdr)
runtime.Assert(err)
defer resp.Body.Close()
defer remote.Close()
local, err := upgrader.Upgrade(w, r, nil)
runtime.Assert(err)
defer local.Close()
cp := func(wg *sync.WaitGroup, dst, src *websocket.Conn) {
defer wg.Done()
defer dst.Close()
defer src.Close()
for {
t, data, err := src.ReadMessage()
if err != nil {
fmt.Println(err)
return
}
err = dst.WriteMessage(t, data)
if err != nil {
fmt.Println(err)
return
}
}
}
var wg sync.WaitGroup
wg.Add(2)
go cp(&wg, local, remote)
go cp(&wg, remote, local)
wg.Wait()
}
func next(w http.ResponseWriter, r *http.Request) {
upgrade := r.Header.Get("Connection")
if upgrade == "Upgrade" {
ws(w, r)
return
}
normal(w, r)
}