134 lines
3.3 KiB
Go
134 lines
3.3 KiB
Go
package server
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"errors"
|
|
"fmt"
|
|
"math/rand"
|
|
"cert"
|
|
"rakshasa/common"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/luyu6056/ishell"
|
|
)
|
|
|
|
func StartRemoteSocks5(cfg *common.Addr, n *node) error {
|
|
|
|
l := &clientListen{
|
|
id: common.GetID(),
|
|
localAddr: "",
|
|
remoteAddr: cfg.Addr(),
|
|
server: n,
|
|
typ: "socks5",
|
|
result: make(chan interface{}),
|
|
randkey: make([]byte,8),
|
|
}
|
|
binary.LittleEndian.PutUint64(l.randkey,uint64(rand.NewSource(time.Now().UnixNano()).Int63()))
|
|
l.openOption = common.CMD_REMOTE_SOCKS5
|
|
l.openMsg = cert.RSAEncrypterByPrivByte(append(l.randkey,cfg.String()...))
|
|
n.Write(l.openOption, l.id, l.openMsg)
|
|
currentNode.listenMap.Store(l.id, l)
|
|
select {
|
|
case res := <-l.result:
|
|
if err, ok := res.(error); ok {
|
|
l.Close(remoteClose)
|
|
return err
|
|
}
|
|
case <-time.After(common.CMD_TIMEOUT):
|
|
l.Close(remoteClose)
|
|
return errors.New("time out")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
func init() {
|
|
remoteSocks5shell := cliInit()
|
|
remoteSocks5shell.SetPrompt("rakshasa\\remotesocks5>")
|
|
remoteSocks5shell.AddCmd(&ishell.Cmd{
|
|
Name: "list",
|
|
Help: "列出当前连接的ID和其他信息",
|
|
Func: func(c *ishell.Context) {
|
|
|
|
var list []*clientListen
|
|
currentNode.listenMap.Range(func(key, value interface{}) bool {
|
|
if v, ok := value.(*clientListen); ok {
|
|
if v.typ == "socks5" {
|
|
list = append(list, v)
|
|
}
|
|
}
|
|
return true
|
|
})
|
|
orderClientListen(list)
|
|
fmt.Println("当前连接数量:", len(list))
|
|
for _, v := range list {
|
|
fmt.Println("ID", v.id, "本地端口", v.localAddr, "远程端口", v.remoteAddr, "服务器uuid", v.server.uuid)
|
|
}
|
|
},
|
|
})
|
|
|
|
remoteSocks5shell.AddCmd(&ishell.Cmd{
|
|
Name: "new-remotesocks5",
|
|
Help: "新建一个remotesocks5连接到本节点,使用方法 new-remotesocks5 配置字串符 目标服务器 如 new-remotesocks5 admin:[email protected]:1080 127.0.0.1:1081",
|
|
Func: func(c *ishell.Context) {
|
|
if len(c.Args) != 2 {
|
|
c.Println("参数错误")
|
|
return
|
|
}
|
|
|
|
n, err := GetNodeFromAddrs(strings.Split(c.Args[1], ","))
|
|
if err != nil {
|
|
c.Println("无法连接 ", c.Args[1], err)
|
|
return
|
|
}
|
|
cfg, err := common.ParseAddr(c.Args[0])
|
|
if err != nil {
|
|
c.Println(err)
|
|
return
|
|
}
|
|
if err = StartRemoteSocks5(cfg, n); err != nil {
|
|
c.Println("连接", c.Args[1], "失败", err)
|
|
return
|
|
}
|
|
c.Println("节点", c.Args[1], "配置信息,", c.Args[0], ",启动socks5 到 本节点 成功")
|
|
},
|
|
})
|
|
remoteSocks5shell.AddCmd(&ishell.Cmd{
|
|
Name: "close",
|
|
Help: "关闭一个remotesocks5连接,使用方法 close ID",
|
|
Func: func(c *ishell.Context) {
|
|
if len(c.Args) != 1 {
|
|
c.Println("参数错误,例子 close 1")
|
|
return
|
|
}
|
|
id, _ := strconv.Atoi(c.Args[0])
|
|
|
|
var l *clientListen
|
|
if value, ok := currentNode.listenMap.Load(uint32(id)); ok {
|
|
if v, ok := value.(*clientListen); ok && v.typ == "socks5" {
|
|
l = v
|
|
}
|
|
|
|
}
|
|
if l == nil {
|
|
c.Println("没有找到ID为", id, "的连接")
|
|
} else {
|
|
l.Close("命令行关闭")
|
|
l.server.Write(common.CMD_DELETE_LISTEN, l.id, l.randkey)
|
|
currentNode.listenMap.Delete(uint32(id))
|
|
|
|
}
|
|
},
|
|
})
|
|
rootCli.AddCmd(&ishell.Cmd{
|
|
Name: "remotesocks5",
|
|
Help: "进入remotesocks5功能",
|
|
Func: func(c *ishell.Context) {
|
|
|
|
remoteSocks5shell.Run()
|
|
|
|
},
|
|
})
|
|
}
|