All checks were successful
Build Multi-Platform Binaries / build-frontend (push) Successful in 30s
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Successful in 48s
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Successful in 48s
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Successful in 58s
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Successful in 1m47s
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Successful in 57s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Successful in 49s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Successful in 1m5s
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Successful in 50s
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Successful in 45s
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Successful in 58s
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Successful in 51s
96 lines
1.7 KiB
Go
96 lines
1.7 KiB
Go
package builtin
|
|
|
|
import (
|
|
"io"
|
|
"log"
|
|
"net"
|
|
"sync"
|
|
|
|
"github.com/gotunnel/pkg/plugin"
|
|
)
|
|
|
|
func init() {
|
|
RegisterClient(NewEchoPlugin())
|
|
}
|
|
|
|
// EchoPlugin 回显插件 - 客户端插件示例
|
|
type EchoPlugin struct {
|
|
config map[string]string
|
|
listener net.Listener
|
|
running bool
|
|
mu sync.Mutex
|
|
}
|
|
|
|
// NewEchoPlugin 创建 Echo 插件
|
|
func NewEchoPlugin() *EchoPlugin {
|
|
return &EchoPlugin{}
|
|
}
|
|
|
|
// Metadata 返回插件信息
|
|
func (p *EchoPlugin) Metadata() plugin.Metadata {
|
|
return plugin.Metadata{
|
|
Name: "echo",
|
|
Version: "1.0.0",
|
|
Type: plugin.PluginTypeApp,
|
|
Source: plugin.PluginSourceBuiltin,
|
|
RunAt: plugin.SideClient,
|
|
Description: "Echo server (client plugin example)",
|
|
Author: "GoTunnel",
|
|
RuleSchema: &plugin.RuleSchema{
|
|
NeedsLocalAddr: false,
|
|
},
|
|
}
|
|
}
|
|
|
|
// Init 初始化插件
|
|
func (p *EchoPlugin) Init(config map[string]string) error {
|
|
p.config = config
|
|
return nil
|
|
}
|
|
|
|
// Start 启动服务
|
|
func (p *EchoPlugin) Start() (string, error) {
|
|
p.mu.Lock()
|
|
defer p.mu.Unlock()
|
|
|
|
if p.running {
|
|
return "", nil
|
|
}
|
|
|
|
ln, err := net.Listen("tcp", "127.0.0.1:0")
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
p.listener = ln
|
|
p.running = true
|
|
|
|
log.Printf("[Echo] Started on %s", ln.Addr().String())
|
|
return ln.Addr().String(), nil
|
|
}
|
|
|
|
// HandleConn 处理连接
|
|
func (p *EchoPlugin) HandleConn(conn net.Conn) error {
|
|
defer conn.Close()
|
|
log.Printf("[Echo] New connection from tunnel")
|
|
_, err := io.Copy(conn, conn)
|
|
return err
|
|
}
|
|
|
|
// Stop 停止服务
|
|
func (p *EchoPlugin) Stop() error {
|
|
p.mu.Lock()
|
|
defer p.mu.Unlock()
|
|
|
|
if !p.running {
|
|
return nil
|
|
}
|
|
|
|
if p.listener != nil {
|
|
p.listener.Close()
|
|
}
|
|
p.running = false
|
|
log.Printf("[Echo] Stopped")
|
|
return nil
|
|
}
|