mirror of
https://github.com/lwch/natpass.git
synced 2024-04-21 12:41:54 +00:00
@@ -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
@@ -1,8 +1,8 @@
|
||||
/bin
|
||||
/test
|
||||
/build
|
||||
/release
|
||||
/tmp
|
||||
/logs
|
||||
/run
|
||||
/*.yaml
|
||||
/*.yaml
|
||||
/test_conf
|
||||
+7
-1
@@ -127,4 +127,10 @@
|
||||
|
||||
# v0.9.1
|
||||
|
||||
1. 修正客户端在断网后会假死的问题
|
||||
1. 修正客户端在断网后会假死的问题
|
||||
|
||||
# v0.10.0
|
||||
|
||||
1. go版本升级到1.18.4
|
||||
2. 新增code-server支持
|
||||
3. 优化disconnect处理逻辑
|
||||
@@ -41,46 +41,34 @@ dashboard页面
|
||||
|
||||

|
||||
|
||||
linux命令行效果
|
||||
命令行
|
||||
|
||||

|
||||
| platform | 386 | amd64 | arm | arm64 |
|
||||
| -------- | :-: | :---: | :-: | :---: |
|
||||
| windows | ✅ | ✅ | ✅ | ✅ |
|
||||
| macos | | ✅ | | ✅ |
|
||||
| linux | ✅ | ✅ | ✅ | ✅ |
|
||||
|
||||
windows命令行效果
|
||||

|
||||
|
||||

|
||||
远程桌面
|
||||
|
||||
windows2008远程桌面
|
||||
| platform | 386 | amd64 | arm | arm64 |
|
||||
| -------- | :-: | :---: | :-: | :---: |
|
||||
| windows | ✅ | ✅ | ❌ | ❌ |
|
||||
| macos | | ✅ | | ✅ |
|
||||
| linux | ✅ | ✅ | ❌ | ❌ |
|
||||
|
||||

|
||||

|
||||
|
||||
windows10远程桌面
|
||||
|
||||

|
||||
|
||||
windows11远程桌面
|
||||
|
||||

|
||||
|
||||
ubuntu远程桌面
|
||||
|
||||

|
||||
|
||||
fedora远程桌面
|
||||
|
||||

|
||||
|
||||
deepin远程桌面
|
||||
|
||||

|
||||
|
||||
macos远程桌面
|
||||
|
||||

|
||||
|
||||
windows读取剪贴板内容
|
||||
windows剪贴板内容
|
||||
|
||||

|
||||
|
||||
code-server支持
|
||||
|
||||

|
||||
|
||||
## 性能
|
||||
|
||||
在vmware环境下创建4C2G(AMD Ryzen 7 4800U with Radeon Graphics)测试环境,并进行all in one部署server、remote端和local端,使用bench规则进行压测,结果如下:
|
||||
|
||||
@@ -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,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 \
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package conn
|
||||
|
||||
func dup(data []byte) []byte {
|
||||
ret := make([]byte, len(data))
|
||||
copy(ret, data)
|
||||
return ret
|
||||
}
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
|
||||
@@ -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
@@ -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:
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
/assets.go
|
||||
@@ -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
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
@@ -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 (
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -5,4 +5,5 @@ link:
|
||||
log:
|
||||
dir: ./logs # 路径,相对于可执行文件所在目录的相对路径
|
||||
size: 50M # 单个文件大小
|
||||
rotate: 7 # 保留数量
|
||||
rotate: 7 # 保留数量
|
||||
codedir: ./code # code-server配置保存路径
|
||||
@@ -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,3 +1,4 @@
|
||||
# 目前不支持arm架构的windows和linux操作系统
|
||||
- name: vnc # 链路名称
|
||||
target: remote # 目标客户端ID
|
||||
type: vnc # web vnc
|
||||
|
||||
@@ -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
@@ -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
|
||||
@@ -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",
|
||||
|
||||
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 90 KiB |
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 141 KiB |
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 2.5 MiB |
@@ -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
|
||||
)
|
||||
|
||||
@@ -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=
|
||||
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../js/common.js
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../fontawesome-free-5.15.4
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../jquery
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>`));
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
Reference in New Issue
Block a user