Files
overlord/Overlord-Client/cmd/agent/handlers/socks5.go
T

192 lines
3.6 KiB
Go
Raw Normal View History

2026-03-05 00:04:26 -06:00
package handlers
import (
"context"
"fmt"
"log"
"net"
"sync"
"time"
"overlord-client/cmd/agent/runtime"
"overlord-client/cmd/agent/wire"
)
var (
2026-03-15 16:14:50 -05:00
tunnelMu sync.Mutex
tunnelConns = make(map[string]*tunnelConn) // connectionId → tunnelConn
2026-03-05 00:04:26 -06:00
)
2026-03-15 16:14:50 -05:00
type tunnelConn struct {
conn net.Conn
cancel context.CancelFunc
}
2026-03-05 00:04:26 -06:00
2026-03-15 16:14:50 -05:00
func HandleProxyConnect(ctx context.Context, env *runtime.Env, connID string, payload map[string]interface{}) error {
host, _ := payload["host"].(string)
portRaw := payload["port"]
var port int
switch v := portRaw.(type) {
case int:
port = v
case int8:
port = int(v)
case int16:
port = int(v)
case int32:
port = int(v)
case int64:
port = int(v)
case uint:
port = int(v)
case uint8:
port = int(v)
case uint16:
port = int(v)
case uint32:
port = int(v)
case uint64:
port = int(v)
case float32:
port = int(v)
case float64:
port = int(v)
}
if host == "" || port <= 0 || port > 65535 {
2026-03-05 00:04:26 -06:00
return wire.WriteMsg(ctx, env.Conn, wire.CommandResult{
Type: "command_result",
2026-03-15 16:14:50 -05:00
CommandID: connID,
2026-03-05 00:04:26 -06:00
OK: false,
2026-03-15 16:14:50 -05:00
Message: "Invalid host or port",
2026-03-05 00:04:26 -06:00
})
}
2026-03-15 16:14:50 -05:00
target := fmt.Sprintf("%s:%d", host, port)
goSafe("tunnel-dial-"+connID, nil, func() {
targetConn, err := net.DialTimeout("tcp", target, 10*time.Second)
if err != nil {
log.Printf("[tunnel] failed to connect to %s: %v", target, err)
_ = wire.WriteMsg(ctx, env.Conn, wire.CommandResult{
Type: "command_result",
CommandID: connID,
OK: false,
Message: fmt.Sprintf("Connection refused: %v", err),
})
return
2026-03-05 00:04:26 -06:00
}
2026-03-15 16:14:50 -05:00
tunnelCtx, tunnelCancel := context.WithCancel(context.Background())
tc := &tunnelConn{conn: targetConn, cancel: tunnelCancel}
tunnelMu.Lock()
tunnelConns[connID] = tc
tunnelMu.Unlock()
// tell the server we connected successfully
if err := wire.WriteMsg(ctx, env.Conn, wire.CommandResult{
2026-03-05 00:04:26 -06:00
Type: "command_result",
2026-03-15 16:14:50 -05:00
CommandID: connID,
OK: true,
Message: "Connected",
}); err != nil {
targetConn.Close()
tunnelCancel()
tunnelMu.Lock()
delete(tunnelConns, connID)
tunnelMu.Unlock()
return
}
2026-03-05 00:04:26 -06:00
2026-03-15 16:14:50 -05:00
defer func() {
tunnelCancel()
targetConn.Close()
tunnelMu.Lock()
delete(tunnelConns, connID)
tunnelMu.Unlock()
_ = wire.WriteMsg(ctx, env.Conn, wire.ProxyClose{
Type: "proxy_close",
ConnectionID: connID,
})
2026-03-05 00:04:26 -06:00
2026-03-15 16:14:50 -05:00
}()
2026-03-05 00:04:26 -06:00
2026-03-15 16:14:50 -05:00
buf := make([]byte, 32*1024)
for {
select {
case <-tunnelCtx.Done():
return
default:
}
n, err := targetConn.Read(buf)
if n > 0 {
data := make([]byte, n)
copy(data, buf[:n])
if writeErr := wire.WriteMsg(ctx, env.Conn, wire.ProxyData{
Type: "proxy_data",
ConnectionID: connID,
Data: data,
}); writeErr != nil {
return
}
}
if err != nil {
return
}
}
})
2026-03-05 00:04:26 -06:00
return nil
}
2026-03-15 16:14:50 -05:00
func HandleProxyData(ctx context.Context, env *runtime.Env, connID string, payload map[string]interface{}) error {
tunnelMu.Lock()
tc, ok := tunnelConns[connID]
tunnelMu.Unlock()
if !ok {
return nil
2026-03-05 00:04:26 -06:00
}
2026-03-15 16:14:50 -05:00
var data []byte
switch v := payload["data"].(type) {
case []byte:
data = v
case string:
data = []byte(v)
2026-03-05 00:04:26 -06:00
default:
2026-03-15 16:14:50 -05:00
return nil
2026-03-05 00:04:26 -06:00
}
2026-03-15 16:14:50 -05:00
if _, err := tc.conn.Write(data); err != nil {
tc.cancel()
return nil
2026-03-05 00:04:26 -06:00
}
2026-03-15 16:14:50 -05:00
return nil
}
2026-03-05 00:04:26 -06:00
2026-03-15 16:14:50 -05:00
func HandleProxyClose(ctx context.Context, env *runtime.Env, connID string) error {
tunnelMu.Lock()
tc, ok := tunnelConns[connID]
if ok {
delete(tunnelConns, connID)
2026-03-05 00:04:26 -06:00
}
2026-03-15 16:14:50 -05:00
tunnelMu.Unlock()
if ok {
tc.cancel()
tc.conn.Close()
}
return nil
}
2026-03-05 00:04:26 -06:00
2026-03-15 16:14:50 -05:00
func CleanupAllTunnels() {
tunnelMu.Lock()
defer tunnelMu.Unlock()
for id, tc := range tunnelConns {
tc.cancel()
tc.conn.Close()
delete(tunnelConns, id)
2026-03-05 00:04:26 -06:00
}
}