complete code, need debug
This commit is contained in:
parent
edd12ff347
commit
c8b2e99003
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
// 使用 IntelliSense 了解相关属性。
|
||||||
|
// 悬停以查看现有属性的描述。
|
||||||
|
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Launch Package client",
|
||||||
|
"type": "go",
|
||||||
|
"request": "launch",
|
||||||
|
"mode": "auto",
|
||||||
|
"program": "${workspaceFolder}/tunnelclient",
|
||||||
|
"args":["--target-session", "HNCZhU8G86HSfTZv", "--local-port", "2222"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Launch Package",
|
||||||
|
"type": "go",
|
||||||
|
"request": "launch",
|
||||||
|
"mode": "auto",
|
||||||
|
"program": "${workspaceFolder}/tunnelserver/main.go"
|
||||||
|
}
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,169 @@
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"git.pyer.club/kingecg/goemitter"
|
||||||
|
"git.pyer.club/kingecg/gotunnelserver/util"
|
||||||
|
ws "github.com/gorilla/websocket"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DataEndPoint struct {
|
||||||
|
Host string
|
||||||
|
Port int
|
||||||
|
|
||||||
|
cmdSession *CommandClient
|
||||||
|
dataSession string
|
||||||
|
wsConn *ws.Conn
|
||||||
|
conns map[int32]*DataConn
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DataEndPoint) Close() {
|
||||||
|
d.wsConn.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DataEndPoint) onDataConnClose(conn *DataConn) {
|
||||||
|
delete(d.conns, conn.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DataEndPoint) Connect() {
|
||||||
|
conn, _, err := ws.DefaultDialer.Dial(d.cmdSession.Address+"/ws/pipe/"+d.dataSession, map[string][]string{
|
||||||
|
"Authorization": {d.cmdSession.makeAuthHeader()},
|
||||||
|
"Session": {d.cmdSession.SessionId},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
d.wsConn = conn
|
||||||
|
for {
|
||||||
|
// d.wsConn.SetReadDeadline(time.Now().Add(time.Minute * 5))
|
||||||
|
_, data, err := d.wsConn.ReadMessage()
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
var packet Packet
|
||||||
|
err = packet.BinaryUnmarshaler(data)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
conn, ok := d.conns[packet.id]
|
||||||
|
if !ok {
|
||||||
|
tcpconn, err := net.Dial("tcp", d.Host+":"+strconv.Itoa(d.Port))
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
conn = NewDataConnection(packet.id, &tcpconn, d)
|
||||||
|
conn.Start()
|
||||||
|
conn.Once("close", func(args ...interface{}) {
|
||||||
|
d.onDataConnClose(conn)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.Write(packet)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DataEndPoint) Listen() {
|
||||||
|
// listen and accept connection at port
|
||||||
|
listener, err := net.Listen("tcp", d.Host+":"+strconv.Itoa(d.Port))
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err, d)
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
conn, err := listener.Accept()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
dconn := NewDataConnection(0, &conn, d)
|
||||||
|
d.conns[dconn.id] = dconn
|
||||||
|
dconn.Start()
|
||||||
|
dconn.Once("close", func(args ...interface{}) {
|
||||||
|
d.onDataConnClose(dconn)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DataEndPoint) Write(p []byte) (n int, err error) {
|
||||||
|
return len(p), d.wsConn.WriteMessage(ws.BinaryMessage, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDataEndPoint(cmdSession *CommandClient, dataSession string) *DataEndPoint {
|
||||||
|
return &DataEndPoint{
|
||||||
|
cmdSession: cmdSession,
|
||||||
|
dataSession: dataSession,
|
||||||
|
conns: make(map[int32]*DataConn),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type DataConn struct {
|
||||||
|
id int32
|
||||||
|
conn *net.Conn
|
||||||
|
out io.Writer
|
||||||
|
*goemitter.EventEmitter
|
||||||
|
}
|
||||||
|
|
||||||
|
type Packet struct {
|
||||||
|
id int32
|
||||||
|
data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Packet) MarshalBinary() ([]byte, error) {
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
binary.Write(buf, binary.LittleEndian, p)
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Packet) BinaryUnmarshaler(data []byte) error {
|
||||||
|
buf := bytes.NewReader(data)
|
||||||
|
return binary.Read(buf, binary.LittleEndian, p)
|
||||||
|
}
|
||||||
|
func (d *DataConn) Close() {
|
||||||
|
(*d.conn).Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DataConn) Write(p Packet) (n int, err error) {
|
||||||
|
return (*d.conn).Write(p.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DataConn) Start() {
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
buf := make([]byte, 1024)
|
||||||
|
n, err := (*d.conn).Read(buf)
|
||||||
|
if err != nil {
|
||||||
|
// panic(err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
packet := Packet{
|
||||||
|
id: d.id,
|
||||||
|
data: buf[:n],
|
||||||
|
}
|
||||||
|
data, err := packet.MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
d.out.Write(data)
|
||||||
|
}
|
||||||
|
d.Emit("close")
|
||||||
|
}()
|
||||||
|
|
||||||
|
}
|
||||||
|
func NewDataConnection(id int32, con *net.Conn, writer io.Writer) *DataConn {
|
||||||
|
cid := id
|
||||||
|
if cid == 0 {
|
||||||
|
cid = util.GenRandomInt()
|
||||||
|
}
|
||||||
|
return &DataConn{
|
||||||
|
id: cid,
|
||||||
|
conn: con,
|
||||||
|
out: writer,
|
||||||
|
EventEmitter: goemitter.NewEmitter(),
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.pyer.club/kingecg/goemitter"
|
||||||
|
"git.pyer.club/kingecg/gotunnelserver/server"
|
||||||
|
"git.pyer.club/kingecg/gotunnelserver/util"
|
||||||
|
ws "github.com/gorilla/websocket"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ClientConfig struct {
|
||||||
|
Username string
|
||||||
|
Salt string
|
||||||
|
Address string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CommandClient struct {
|
||||||
|
*ws.Conn
|
||||||
|
*goemitter.EventEmitter
|
||||||
|
*ClientConfig
|
||||||
|
path string
|
||||||
|
SessionId string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CommandClient) Close() {
|
||||||
|
if c.Conn != nil {
|
||||||
|
c.Conn.Close()
|
||||||
|
c.Conn = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CommandClient) Send(cmd *server.Command) (err error) {
|
||||||
|
return c.WriteJSON(cmd)
|
||||||
|
}
|
||||||
|
func (c *CommandClient) Start() {
|
||||||
|
defer c.Close()
|
||||||
|
// cpath:="/client"
|
||||||
|
// if c.IsAgent {
|
||||||
|
// cpath = "/agent"
|
||||||
|
// }
|
||||||
|
authHeader := c.makeAuthHeader()
|
||||||
|
conn, _, err := ws.DefaultDialer.Dial(c.Address+c.path, map[string][]string{
|
||||||
|
"Authorization": {authHeader},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
c.Conn = conn
|
||||||
|
c.On(util.CmdTypeMap[util.NewSession], func(args ...interface{}) {
|
||||||
|
playload, _ := args[0].(map[string]string)
|
||||||
|
sessionId := playload["sessionId"]
|
||||||
|
log.Println("new session:", sessionId)
|
||||||
|
c.SessionId = sessionId
|
||||||
|
})
|
||||||
|
for {
|
||||||
|
var cmd server.Command
|
||||||
|
err := c.ReadJSON(&cmd)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
eventLabel := util.CmdTypeMap[cmd.Type]
|
||||||
|
log.Println("cmd:", cmd.Type, eventLabel)
|
||||||
|
c.Emit(eventLabel, cmd.Payload)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CommandClient) makeAuthHeader() string {
|
||||||
|
a := &util.AuthEntity{
|
||||||
|
Entity: util.Entity{
|
||||||
|
Username: c.Username,
|
||||||
|
},
|
||||||
|
Time: time.Now().Unix(),
|
||||||
|
}
|
||||||
|
a.Authtoken = util.GenAuthToken(a, c.Salt)
|
||||||
|
str, err := json.Marshal(a)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return base64.StdEncoding.EncodeToString(str)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClient(conf *ClientConfig) *CommandClient {
|
||||||
|
return &CommandClient{
|
||||||
|
ClientConfig: conf,
|
||||||
|
EventEmitter: goemitter.NewEmitter(),
|
||||||
|
path: "/ws/client",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAgent(conf *ClientConfig) *CommandClient {
|
||||||
|
return &CommandClient{
|
||||||
|
ClientConfig: conf,
|
||||||
|
EventEmitter: goemitter.NewEmitter(),
|
||||||
|
path: "/ws/agent",
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestClient(t *testing.T) {
|
||||||
|
clientConfig := &ClientConfig{
|
||||||
|
Address: "ws://localhost:8080",
|
||||||
|
Salt: "",
|
||||||
|
Username: "test",
|
||||||
|
}
|
||||||
|
client := NewClient(clientConfig)
|
||||||
|
client.Start()
|
||||||
|
}
|
1
go.mod
1
go.mod
|
@ -3,6 +3,7 @@ module git.pyer.club/kingecg/gotunnelserver
|
||||||
go 1.23.1
|
go 1.23.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
git.pyer.club/kingecg/command v0.0.0-20241115071005-9f26d1cf2992 // indirect
|
||||||
git.pyer.club/kingecg/goemitter v0.0.0-20240919084107-533c3d1be082 // indirect
|
git.pyer.club/kingecg/goemitter v0.0.0-20240919084107-533c3d1be082 // indirect
|
||||||
git.pyer.club/kingecg/gologger v1.0.5 // indirect
|
git.pyer.club/kingecg/gologger v1.0.5 // indirect
|
||||||
github.com/gorilla/websocket v1.5.3 // indirect
|
github.com/gorilla/websocket v1.5.3 // indirect
|
||||||
|
|
6
go.sum
6
go.sum
|
@ -1,3 +1,9 @@
|
||||||
|
git.pyer.club/kingecg/command v0.0.0-20241024110012-525a2ad9662d h1:CIcY8L5FcGy1uO+GvdMeidjdfYSxwTEEEvt3WXBOQAU=
|
||||||
|
git.pyer.club/kingecg/command v0.0.0-20241024110012-525a2ad9662d/go.mod h1:lnSzW19xOIlUwlewxHH0R4SIDO+a4++USjmMjo/jZB0=
|
||||||
|
git.pyer.club/kingecg/command v0.0.0-20241115051719-6fd5111300dc h1:PVvfibld+xRlWIbBlprF0AaIuTpF5QeY3CqthCQP8lg=
|
||||||
|
git.pyer.club/kingecg/command v0.0.0-20241115051719-6fd5111300dc/go.mod h1:7j+/UU5URp7UkTbNtYDvZY3cFywuTRys1TmP3HbNX3A=
|
||||||
|
git.pyer.club/kingecg/command v0.0.0-20241115071005-9f26d1cf2992 h1:QurLvSlNSU2TjTVe9h9+N9QVZEvSXuz9POebExqhfOo=
|
||||||
|
git.pyer.club/kingecg/command v0.0.0-20241115071005-9f26d1cf2992/go.mod h1:7j+/UU5URp7UkTbNtYDvZY3cFywuTRys1TmP3HbNX3A=
|
||||||
git.pyer.club/kingecg/goemitter v0.0.0-20240919084107-533c3d1be082 h1:U7Jbet3zObT2qPJ2g408Z9OUvR6phQyHOoHeidM5zUg=
|
git.pyer.club/kingecg/goemitter v0.0.0-20240919084107-533c3d1be082 h1:U7Jbet3zObT2qPJ2g408Z9OUvR6phQyHOoHeidM5zUg=
|
||||||
git.pyer.club/kingecg/goemitter v0.0.0-20240919084107-533c3d1be082/go.mod h1:2jbknDqoWH41M3MQ9pQZDKBiNtDmNgPcM3XfkE9YkbQ=
|
git.pyer.club/kingecg/goemitter v0.0.0-20240919084107-533c3d1be082/go.mod h1:2jbknDqoWH41M3MQ9pQZDKBiNtDmNgPcM3XfkE9YkbQ=
|
||||||
git.pyer.club/kingecg/gologger v1.0.5 h1:L/N/bleGHhEiaBYBf9U1z2ni0HfhaU71pk8ik/D11oo=
|
git.pyer.club/kingecg/gologger v1.0.5 h1:L/N/bleGHhEiaBYBf9U1z2ni0HfhaU71pk8ik/D11oo=
|
||||||
|
|
|
@ -3,7 +3,6 @@ package server
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"git.pyer.club/kingecg/gotunnelserver/util"
|
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -11,11 +10,6 @@ func (s *Server) HandleAgent(c *websocket.Conn, r *http.Request) {
|
||||||
agentSession := NewSession(c)
|
agentSession := NewSession(c)
|
||||||
agentSession.Start()
|
agentSession.Start()
|
||||||
s.agentSession[agentSession.Id] = agentSession
|
s.agentSession[agentSession.Id] = agentSession
|
||||||
command := &Command{
|
command := NcmdSession(agentSession.Id)
|
||||||
Type: util.NewSession,
|
|
||||||
Payload: map[string]string{
|
|
||||||
"id": agentSession.Id,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
agentSession.Send(command)
|
agentSession.Send(command)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,9 @@ func (s *Server) HandleClient(conn *websocket.Conn, r *http.Request) {
|
||||||
clientSession.Send(NewErrorResponse("target session not found", command))
|
clientSession.Send(NewErrorResponse("target session not found", command))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
command := NcmdConnectionInited(clientSession.Id)
|
spipe := NewPipe(clientSession.Id, targetSessionId)
|
||||||
|
s.pipes[spipe.Id] = spipe
|
||||||
|
command := NcmdConnectionInited(spipe.Id)
|
||||||
|
|
||||||
for k, v := range orgPlayload {
|
for k, v := range orgPlayload {
|
||||||
command.Payload[k] = v
|
command.Payload[k] = v
|
||||||
|
|
|
@ -3,6 +3,7 @@ package server
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"git.pyer.club/kingecg/gotunnelserver/util"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -23,6 +24,14 @@ func (p *Pipe) Start() {
|
||||||
p.src.Close()
|
p.src.Close()
|
||||||
p.dst.Close()
|
p.dst.Close()
|
||||||
}
|
}
|
||||||
|
func NewPipe(src, dst string) *Pipe {
|
||||||
|
return &Pipe{
|
||||||
|
Id: util.GenRandomstring(16),
|
||||||
|
Src: src,
|
||||||
|
Dst: dst,
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Pipe) forward(src, dst *websocket.Conn) {
|
func (p *Pipe) forward(src, dst *websocket.Conn) {
|
||||||
for {
|
for {
|
||||||
|
@ -75,7 +84,7 @@ func (s *Server) HandlePipe(conn *websocket.Conn, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if pipe.src != nil && pipe.dst != nil {
|
if pipe.src != nil && pipe.dst != nil {
|
||||||
pipe.Start()
|
go pipe.Start()
|
||||||
clientCmdSession := s.findSession(pipe.Src)
|
clientCmdSession := s.findSession(pipe.Src)
|
||||||
clientCmdSession.Send(NcmdConnectionReady(pipe.Id)) // info src endpoint ready and can setup proxy listener
|
clientCmdSession.Send(NcmdConnectionReady(pipe.Id)) // info src endpoint ready and can setup proxy listener
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,7 @@ func (s *Server) registHandler() {
|
||||||
s.mux = http.NewServeMux()
|
s.mux = http.NewServeMux()
|
||||||
}
|
}
|
||||||
s.mux.HandleFunc("/hello", s.HandleHello)
|
s.mux.HandleFunc("/hello", s.HandleHello)
|
||||||
s.mux.HandleFunc("/ws", s.HandleWs)
|
s.mux.HandleFunc("/ws/", s.HandleWs)
|
||||||
}
|
}
|
||||||
func (s *Server) Start() {
|
func (s *Server) Start() {
|
||||||
addr := s.Config.Host + ":" + s.Config.Port
|
addr := s.Config.Host + ":" + s.Config.Port
|
||||||
|
|
|
@ -92,7 +92,7 @@ func NewErrorResponse(err string, cmd *Command) *Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NcmdConnectionInited(sessionId string) *Command {
|
func NcmdConnectionInited(sessionId string) *Command {
|
||||||
return NewCommand(util.ConnectionReady, map[string]string{"sessionId": sessionId})
|
return NewCommand(util.ConnectInited, map[string]string{"sessionId": sessionId})
|
||||||
}
|
}
|
||||||
|
|
||||||
func NcmdConnectionReady(sessionId string) *Command {
|
func NcmdConnectionReady(sessionId string) *Command {
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"git.pyer.club/kingecg/command"
|
||||||
|
"git.pyer.club/kingecg/gotunnelserver/client"
|
||||||
|
"git.pyer.club/kingecg/gotunnelserver/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TunnelAgent struct {
|
||||||
|
Username string `flag_default:"tcclient" flag_usage:"username for tunnel server"`
|
||||||
|
Salt string `flag_default:"" flag_usage:"salt for tunnel server"`
|
||||||
|
Address string `flag_default:"ws://127.0.0.1:8080" flag_usage:"address for tunnel server"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
cmdClient *client.CommandClient
|
||||||
|
dataEp *client.DataEndPoint
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
cargs := new(TunnelAgent)
|
||||||
|
v, _ := command.NewFVSet(cargs)
|
||||||
|
err := command.Parse(os.Args[1:], v)
|
||||||
|
if err != nil {
|
||||||
|
os.Exit(0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
clientConfig := &client.ClientConfig{
|
||||||
|
Username: cargs.Username,
|
||||||
|
Salt: cargs.Salt,
|
||||||
|
Address: cargs.Address,
|
||||||
|
}
|
||||||
|
cmdClient = client.NewAgent(clientConfig)
|
||||||
|
cmdClient.On(util.CmdTypeMap[util.ConnectInited], func(args ...interface{}) {
|
||||||
|
playload, _ := args[0].(map[string]string)
|
||||||
|
sessionId := playload["sessionId"]
|
||||||
|
dataEp = client.NewDataEndPoint(cmdClient, sessionId)
|
||||||
|
dataEp.Host = playload["host"]
|
||||||
|
dataEp.Port, _ = strconv.Atoi(playload["port"])
|
||||||
|
log.Println("connect inited:", sessionId, dataEp.Host, dataEp.Port)
|
||||||
|
go dataEp.Connect()
|
||||||
|
})
|
||||||
|
cmdClient.On(util.CmdTypeMap[util.ErrorCmd], func(args ...interface{}) {
|
||||||
|
playload, _ := args[0].(map[string]string)
|
||||||
|
log.Println("error:", playload["error"])
|
||||||
|
os.Exit(1)
|
||||||
|
})
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
log.Println(r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
cmdClient.Start()
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"git.pyer.club/kingecg/command"
|
||||||
|
"git.pyer.club/kingecg/gotunnelserver/client"
|
||||||
|
"git.pyer.club/kingecg/gotunnelserver/server"
|
||||||
|
"git.pyer.club/kingecg/gotunnelserver/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TunnelClient struct {
|
||||||
|
TargetSession string `flag_default:"" flag_usage:"target session id"`
|
||||||
|
Username string `flag_default:"tcclient" flag_usage:"username for tunnel server"`
|
||||||
|
Salt string `flag_default:"" flag_usage:"salt for tunnel server"`
|
||||||
|
Address string `flag_default:"ws://127.0.0.1:8080" flag_usage:"address for tunnel server"`
|
||||||
|
Host string `flag_default:"127.0.0.1" flag_usage:"host to proxy to"`
|
||||||
|
Port int `flag_default:"22" flag_usage:"port to proxy to"`
|
||||||
|
LocalPort int `flag_default:"0" flag_usage:"local port to accept connection from"`
|
||||||
|
LocalHost string `flag_default:"127.0.0.1" flag_usage:"local host to accept connection from"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
cmdClient *client.CommandClient
|
||||||
|
dataEp *client.DataEndPoint
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
cargs := new(TunnelClient)
|
||||||
|
v, _ := command.NewFVSet(cargs)
|
||||||
|
err := command.Parse(os.Args[1:], v)
|
||||||
|
if err != nil {
|
||||||
|
os.Exit(0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if cargs.TargetSession == "" {
|
||||||
|
log.Fatal("Must set target session to connect to")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
clientConfig := &client.ClientConfig{
|
||||||
|
Username: cargs.Username,
|
||||||
|
Salt: cargs.Salt,
|
||||||
|
Address: cargs.Address,
|
||||||
|
}
|
||||||
|
cmdClient = client.NewClient(clientConfig)
|
||||||
|
cmdClient.Once(util.CmdTypeMap[util.ConnectInited], func(args ...interface{}) {
|
||||||
|
playload, _ := args[0].(map[string]string)
|
||||||
|
sessionId := playload["sessionId"]
|
||||||
|
dataEp = client.NewDataEndPoint(cmdClient, sessionId)
|
||||||
|
dataEp.Host = cargs.LocalHost
|
||||||
|
dataEp.Port = cargs.LocalPort
|
||||||
|
go dataEp.Connect()
|
||||||
|
})
|
||||||
|
cmdClient.On(util.CmdTypeMap[util.NewSession], func(args ...interface{}) {
|
||||||
|
cmdClient.Send(&server.Command{
|
||||||
|
Type: util.NewConnection,
|
||||||
|
Payload: map[string]string{
|
||||||
|
"target": cargs.TargetSession,
|
||||||
|
"host": cargs.Host,
|
||||||
|
"port": strconv.Itoa(cargs.Port),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
cmdClient.Once(util.CmdTypeMap[util.ConnectionReady], func(args ...interface{}) {
|
||||||
|
go dataEp.Listen()
|
||||||
|
log.Println("connection ready")
|
||||||
|
})
|
||||||
|
|
||||||
|
cmdClient.On(util.CmdTypeMap[util.ErrorCmd], func(args ...interface{}) {
|
||||||
|
playload, _ := args[0].(map[string]string)
|
||||||
|
log.Println("error:", playload["error"])
|
||||||
|
os.Exit(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
log.Println(r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
cmdClient.Start()
|
||||||
|
}
|
Binary file not shown.
|
@ -7,3 +7,13 @@ const (
|
||||||
ConnectionReady
|
ConnectionReady
|
||||||
ErrorCmd
|
ErrorCmd
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
CmdTypeMap = map[int]string{
|
||||||
|
NewSession: "new_session",
|
||||||
|
NewConnection: "new_connection",
|
||||||
|
ConnectInited: "connect_inited",
|
||||||
|
ConnectionReady: "connection_ready",
|
||||||
|
ErrorCmd: "error",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
|
@ -57,3 +57,8 @@ func GenRandomstring(n int) string {
|
||||||
}
|
}
|
||||||
return string(b)
|
return string(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GenRandomInt() int32 {
|
||||||
|
// rand.Seed(time.Now().UnixNano())
|
||||||
|
return int32(rand.Intn(65534) + 1)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue