diff --git a/rakshasa_lite/common/cmd.go b/rakshasa_lite/common/cmd.go index a2ef31a..314c4f9 100644 --- a/rakshasa_lite/common/cmd.go +++ b/rakshasa_lite/common/cmd.go @@ -2,17 +2,20 @@ package common import ( "bytes" + "encoding/binary" "errors" "fmt" - "github.com/google/uuid" "math/rand" "net" "rakshasa_lite/aes" "regexp" + "strconv" "strings" "sync" "sync/atomic" "time" + + "github.com/google/uuid" ) const UUID_LEN = 16 @@ -189,16 +192,7 @@ func init() { } -type RegMsg struct { - UUID string //当前机器uuid - RegAddr string //远程连接的addr - Hostname string //当前机器名称 - Goos string - ViaUUID string - Err string - MainIp string - Port string -} + var msgId uint32 @@ -323,3 +317,31 @@ func ResolveTCPAddr(str string) ([]string, error) { return dst, nil } +func GetUUIDFromInterfaceMac() string { + ifts, _ := net.Interfaces() + for _, ift := range ifts { + if addr := ift.HardwareAddr.String(); len(addr) > 0 { + var randSeed = make([]byte, 8) + for k, s := range strings.Split(addr, ":") { + if k < 8 { + n, _ := strconv.ParseUint(s, 16, 8) + randSeed[k] = byte(n) + } + + } + source := rand.NewSource(int64(binary.LittleEndian.Uint64(randSeed))) + buf := bytes.NewBuffer(nil) + for i := 0; i < 2; i++ { + var b = make([]byte, 8) + binary.LittleEndian.PutUint64(b, uint64(source.Int63())) + buf.Write(b) + } + id, err := uuid.NewRandomFromReader(buf) + if err == nil { + return id.String() + } + } + + } + return uuid.New().String() +} \ No newline at end of file diff --git a/rakshasa_lite/common/config.go b/rakshasa_lite/common/config.go index ab9880e..d88be0d 100644 --- a/rakshasa_lite/common/config.go +++ b/rakshasa_lite/common/config.go @@ -1,6 +1,7 @@ package common type Config struct { + UUID string //以指定uuid启动 DstNode []string //-d 上级节点 Password string //通讯密码,可为空 Port int //默认8883 diff --git a/rakshasa_lite/httppool/check_proxy.go b/rakshasa_lite/httppool/check_proxy.go deleted file mode 100644 index 310c5aa..0000000 --- a/rakshasa_lite/httppool/check_proxy.go +++ /dev/null @@ -1,63 +0,0 @@ -package httppool - -import ( - "bufio" - "errors" - "fmt" - "io" - "os" - "rakshasa_lite/common" - "strings" - "sync" -) - -type HttpPool struct { - r *bufio.Reader - f *os.File - sync.Mutex -} - -func HttpPoolInit(file string) (*HttpPool, error) { - f, err := os.Open(file) - if err != nil { - return nil, fmt.Errorf("打开http代理池文件 %s 失败", file) - } - p := &HttpPool{ - r: bufio.NewReader(f), - f: f, - Mutex: sync.Mutex{}, - } - if _, err = p.do_next(0); err != nil { - return nil, fmt.Errorf("无法从%s文件获取代理,错误%v", file, err) - } - return p, nil -} -func (p *HttpPool) Next() *common.Addr { - addr, _ := p.do_next(0) - return addr -} -func (p *HttpPool) do_next(n int) (*common.Addr, error) { - if n > 100 { - return nil, errors.New("重试错误次数过多") - } - p.Lock() - line, err := p.r.ReadString(10) - if err == io.EOF { - p.f.Seek(0, 0) - p.r.Reset(p.f) - p.Unlock() - return p.do_next(n + 1) - } - p.Unlock() - line = strings.TrimRight(line, "\n") - line = strings.TrimRight(line, "\r") - - if len(line) == 0 { - return p.do_next(n + 1) - } - addr, err := common.ParseAddr(line) - if err != nil { - return p.do_next(n + 1) - } - return addr, nil -} diff --git a/rakshasa_lite/main.go b/rakshasa_lite/main.go index b719ae2..4971071 100644 --- a/rakshasa_lite/main.go +++ b/rakshasa_lite/main.go @@ -10,6 +10,8 @@ import ( "rakshasa_lite/server" "strconv" "sync" + + "github.com/google/uuid" ) func main() { @@ -34,6 +36,8 @@ func main() { shellCodeTimeout = flag.Int("sTimeout", 3, "shellcode的超时等待时间,默认3秒") http_proxy = flag.String("http_proxy", "", "以本地http代理服务端模式运行,通过-d的服务器多级代理转出数据,如果没有-d参数,则使用本机进行下一步连接, 用户名:密码@ip:端口 可以省略为端口,如: \r\n -http_proxy admin:12345@0.0.0.0:8080\r\n -http_proxy admin:12345@8080\r\n -http_proxy 8080") http_proxy_pool = flag.String("http_proxy_pool", "", "从指定文件读取http代理服务器池,通过最后节点后(不使用-d则为本机),再从该池里读取一个代理进行请求") + withUUID = flag.String("uuid", "", "以指定uuid启动,如果uuid非法或者为空,则以网卡mac方式生成uuid") + randomUUID = flag.Bool("randomUUID", false, "每次启动,都使用随机的uuid") ) flag.Parse() @@ -52,7 +56,11 @@ func main() { } } - + if *randomUUID { + config.UUID = uuid.New().String() + } else if *withUUID != "" { + config.UUID = *withUUID + } if *dstNode != "" { serverlist, err := common.ResolveTCPAddr(*dstNode) if err != nil { @@ -105,7 +113,7 @@ func main() { if *shellCode != "" { server.RunShellcodeWithDst(*dstNode, *shellCode, *shellCodeXorKey, *shellCodeParam, *shellCodeTimeout) } - if err := server.StartServer(fmt.Sprintf("0.0.0.0:%d", config.Port)); err != nil { + if err := server.StartServer(fmt.Sprintf(":%d", config.Port)); err != nil { log.Fatalln(err) } diff --git a/rakshasa_lite/server/config.go b/rakshasa_lite/server/config.go index 638916f..ab87191 100644 --- a/rakshasa_lite/server/config.go +++ b/rakshasa_lite/server/config.go @@ -1,6 +1,7 @@ package server import ( + "github.com/google/uuid" "gopkg.in/yaml.v3" "io/ioutil" "rakshasa_lite/common" @@ -13,6 +14,12 @@ func SetConfig(config common.Config) { currentConfig.FileSave = false currentNode.mainIp = currentConfig.ListenIp currentNode.port = currentConfig.Port + if id, err := uuid.Parse(currentConfig.UUID); err != nil { + currentConfig.UUID = common.GetUUIDFromInterfaceMac() + }else{ + currentConfig.UUID=id.String() + } + currentNode.uuid = currentConfig.UUID } func ConfigSave() error { b, _ := yaml.Marshal(currentConfig) diff --git a/rakshasa_lite/server/conn.go b/rakshasa_lite/server/conn.go index 5f9cf80..e331635 100644 --- a/rakshasa_lite/server/conn.go +++ b/rakshasa_lite/server/conn.go @@ -39,8 +39,7 @@ type Conn struct { close chan string isClient bool nodeConn *tls.Conn - regResult chan error - regResultNode chan *node + regResult chan RegMsg } type serverListen struct { @@ -531,7 +530,7 @@ func (c *Conn) handlerNodeRead() { } } case <-time.After(common.CMD_TIMEOUT): - newNode.Delete("超时") + newNode.Close("超时") } }() @@ -626,7 +625,7 @@ func (c *Conn) handle() { } } - case <-c.close: + case reason := <-c.close: c.OutChan = upNodeWrite if c.node != nil && c.node.nextPingTime > time.Now().Unix()+5 { c.node.ping(0) @@ -646,6 +645,7 @@ func (c *Conn) handle() { } if c.node != nil { + c.node.Close(reason) //移除上游连接 for i := len(upLevelNode) - 1; i >= 0; i-- { n := upLevelNode[i] @@ -668,7 +668,7 @@ func (c *Conn) handle() { func (c *Conn) reg() error { var err error - reg := &common.RegMsg{ + reg := &RegMsg{ UUID: currentNode.uuid, MainIp: cert.RSAEncrypterStr(currentNode.mainIp), Port: cert.RSAEncrypterStr(strconv.Itoa(currentNode.port)), diff --git a/rakshasa_lite/server/http_proxy.go b/rakshasa_lite/server/http_proxy.go index 86a7eb4..3a405d8 100644 --- a/rakshasa_lite/server/http_proxy.go +++ b/rakshasa_lite/server/http_proxy.go @@ -1,16 +1,19 @@ package server import ( + "bufio" "bytes" "cert" "encoding/binary" + "errors" "fmt" + "io" "log" "math/rand" "net" "net/url" + "os" "rakshasa_lite/common" - "rakshasa_lite/httppool" "strings" "sync" "sync/atomic" @@ -19,7 +22,7 @@ import ( type httpProxyClient struct { windowsSize int64 - isclose int32 + status int32 conn net.Conn udpconn net.Conn @@ -32,10 +35,9 @@ type httpProxyClient struct { udpMap sync.Map listenId uint32 localAddr string - isConnect bool method string cfg *common.Addr - pool *httppool.HttpPool + pool *httpPool remoteAddr string remotePort string randkey []byte @@ -60,7 +62,9 @@ func (s *httpProxyClient) Write(b []byte) { if b[10] != 1 { //重新拉取一个池 - s.connect() + if !s.connect() { + s.Close(nodeIsClose) + } } else if s.method == "CONNECT" { s.conn.Write([]byte("HTTP/1.0 200 Connection established\r\n\r\n")) } @@ -78,7 +82,7 @@ func (s *httpProxyClient) Write(b []byte) { } func (s *httpProxyClient) Close(msg string) { - if atomic.CompareAndSwapInt32(&s.isclose, 0, 1) { + if atomic.CompareAndSwapInt32(&s.status, CONN_STATUS_CONNECT, CONN_STATUS_NONE) { <-s.wait s.wait <- common.CONN_STATUS_CLOSE @@ -133,10 +137,10 @@ func (s *httpProxyClient) Addwindow(window int64) { } func StartHttpProxy(cfg *common.Addr, dst []string, poolfile string) error { - var pool *httppool.HttpPool + var pool *httpPool var err error if poolfile != "" { - pool, err = httppool.HttpPoolInit(poolfile) + pool, err = httpPoolInit(poolfile) if err != nil { return err } @@ -169,7 +173,7 @@ func StartHttpProxy(cfg *common.Addr, dst []string, poolfile string) error { currentNode.listenMap.Store(l.id, l) return nil } -func StartHttpProxyWithServer(cfg *common.Addr, n *node, id uint32, pool *httppool.HttpPool) (net.Listener, error) { +func StartHttpProxyWithServer(cfg *common.Addr, n *node, id uint32, pool *httpPool) (net.Listener, error) { l, err := net.Listen("tcp", cfg.Addr()) if err != nil { return nil, err @@ -265,20 +269,23 @@ func handleHttpProxyLocal(s *httpProxyClient) { s.remoteAddr = u.Host s.remotePort = "80" } - s.connect() - buf := bufPool.Get().(*bytes.Buffer) - buf.Reset() - buf.WriteString("GET ") - buf.WriteString(req.uri) - buf.WriteString(" HTTP/1.1\r\n") - for _, header := range req.header { - buf.WriteString(header) + if s.connect() { + buf := bufPool.Get().(*bytes.Buffer) + buf.Reset() + buf.WriteString("GET ") + buf.WriteString(req.uri) + buf.WriteString(" HTTP/1.1\r\n") + for _, header := range req.header { + buf.WriteString(header) + buf.WriteString("\r\n") + } buf.WriteString("\r\n") + s.write2connect(buf.Bytes()) + buf.Reset() + bufPool.Put(buf) + } else { + s.Close(nodeIsClose) } - buf.WriteString("\r\n") - s.write2connect(buf.Bytes()) - buf.Reset() - bufPool.Put(buf) } else { return @@ -288,7 +295,9 @@ func handleHttpProxyLocal(s *httpProxyClient) { if i := strings.IndexByte(req.uri, ':'); i > -1 { s.remoteAddr = req.uri[:i] s.remotePort = req.uri[i+1:] - s.connect() + if !s.connect() { + s.Close(nodeIsClose) + } } else { return } @@ -329,9 +338,8 @@ func (s *httpProxyClient) write2connect(data []byte) { s.server.Write(common.CMD_CONN_MSG, s.id, append(outdata, data...)) } -func (s *httpProxyClient) connect() { - if !s.isConnect { - +func (s *httpProxyClient) connect() bool { + if !s.checkConnect() { buf := make([]byte, 2+len(s.remoteAddr)+len(s.remotePort)) s.id = s.server.storeConn(s) buf[0] = byte(common.RAW_TCP) @@ -354,11 +362,22 @@ func (s *httpProxyClient) connect() { v.connMap.Store(s.id, s) } } - s.isConnect = true + s.status = CONN_STATUS_CONNECT + return true } - + return s.server.isClose == 0 } +// 检查一下server是否断开,尝试重连,返回是否连接 +func (s *httpProxyClient) checkConnect() bool { + if s.server.isClose == 1 { + //尝试重连 + if newNode, _ := GetNodeFromAddrs(s.server.reConnectAddrs); newNode != nil { + s.server = newNode + } + } + return s.status == CONN_STATUS_CONNECT +} func (s *httpProxyClient) Remoteclose() { s.close = "本地要求远程关闭" @@ -505,3 +524,54 @@ func parsereq(req *http1request, data []byte) (clen int, resdata []byte, err err return 0, nil, nil } + +type httpPool struct { + r *bufio.Reader + f *os.File + sync.Mutex +} + +func httpPoolInit(file string) (*httpPool, error) { + f, err := os.Open(file) + if err != nil { + return nil, fmt.Errorf("打开http代理池文件 %s 失败", file) + } + p := &httpPool{ + r: bufio.NewReader(f), + f: f, + Mutex: sync.Mutex{}, + } + if _, err = p.do_next(0); err != nil { + return nil, fmt.Errorf("无法从%s文件获取代理,错误%v", file, err) + } + return p, nil +} +func (p *httpPool) Next() *common.Addr { + addr, _ := p.do_next(0) + return addr +} +func (p *httpPool) do_next(n int) (*common.Addr, error) { + if n > 100 { + return nil, errors.New("重试错误次数过多") + } + p.Lock() + line, err := p.r.ReadString(10) + if err == io.EOF { + p.f.Seek(0, 0) + p.r.Reset(p.f) + p.Unlock() + return p.do_next(n + 1) + } + p.Unlock() + line = strings.TrimRight(line, "\n") + line = strings.TrimRight(line, "\r") + + if len(line) == 0 { + return p.do_next(n + 1) + } + addr, err := common.ParseAddr(line) + if err != nil { + return p.do_next(n + 1) + } + return addr, nil +} diff --git a/rakshasa_lite/server/node.go b/rakshasa_lite/server/node.go index 13f24e1..cf690bf 100644 --- a/rakshasa_lite/server/node.go +++ b/rakshasa_lite/server/node.go @@ -20,12 +20,10 @@ import ( "sync/atomic" "time" "unsafe" - - uuid2 "github.com/google/uuid" ) var ( - currentNode = &node{uuid: uuid2.New().String()} + currentNode = &node{} clientLock = &lock{} nodeMap = make(map[string]*node) upLevelNode []*node //上游节点 @@ -34,6 +32,18 @@ var ( connMap sync.Map ) +type RegMsg struct { + UUID string //当前机器uuid + RegAddr string //远程连接的addr + Hostname string //当前机器名称 + Goos string + ViaUUID string + Err string + MainIp string + Port string + node *node +} + func InitCurrentNode() { s := unsafe.Sizeof(uintptr(1)) bit := " x32" @@ -87,13 +97,13 @@ func checkUpLevelNode() { //尝试重新连接节点 for _, addr := range currentConfig.DstNode { - connectNew(addr) + getNode(addr) } if len(upLevelNode) == 0 { //尝试连接其他节点 if !currentConfig.Limit { for _, addr := range extNodeIp { - connectNew(addr) + getNode(addr) if len(upLevelNode) > 0 { return } @@ -111,7 +121,7 @@ func checkUpLevelNode() { defer clientLock.RLock(l) if len(n.mainIp) == 0 { - connectNew(fmt.Sprintf("%s:%d", n.addr, n.port)) + getNode(fmt.Sprintf("%s:%d", n.addr, n.port)) } }() if len(upLevelNode) > 0 { @@ -195,16 +205,19 @@ type nodeInfo struct { } func connectNew(addr string) (n *node, e error) { - //先从已连接查找 - for _, node := range nodeMap { - if fmt.Sprintf("%s:%d", node.mainIp, node.port) == addr { - return node, nil - } else if fmt.Sprintf("%s:%d", node.addr, node.port) == addr { - return node, nil - } else if node.uuid == addr { - return node, nil + defer func() { + if n != nil { + find := false + for _, upN := range upLevelNode { + if upN.uuid == n.uuid { + find = true + } + } + if !find { + upLevelNode = append(upLevelNode, n) + } } - } + }() config := cert.Tlsconfig.Clone() interfaces, err := net.Interfaces() if err != nil { @@ -223,7 +236,7 @@ func connectNew(addr string) (n *node, e error) { localstr := localAddr.String() localstr = localstr[:strings.LastIndex(localstr, "/")] + ":0" laddr, _ := net.ResolveTCPAddr("tcp", localstr) - if laddr!=nil{ + if laddr != nil { if netconn, e := net.DialTCP("tcp", laddr, raddr); e == nil { conn := tls.Client(netconn, config) select { @@ -246,34 +259,49 @@ func connectNew(addr string) (n *node, e error) { } c := &Conn{nodeConn: conn, isClient: true, nodeaddr: addr, remoteAddr: conn.LocalAddr().String()} connMap.Store(c.remoteAddr, conn) - c.regResult = make(chan error, 1) - c.regResultNode = make(chan *node, 1) + c.regResult = make(chan RegMsg, 1) c.handle() c.reg() - defer func() { - if c.node != nil { - l := clientLock.Lock() - find := false - for _, n := range upLevelNode { - if n.uuid == c.node.uuid { - find = true + select { + case regmsg := <-c.regResult: + if regmsg.Err != "" { + return nil, errors.New(regmsg.Err) + } + n = regmsg.node + n.uuid = regmsg.UUID + n.hostName = cert.RSADecrypterStr(regmsg.Hostname) + n.goos = cert.RSADecrypterStr(regmsg.Goos) + n.addr = n.conn.nodeConn.RemoteAddr().String() + if i := strings.Index(n.addr, ":"); i > -1 { + n.addr = n.addr[:i] + } + + n.mainIp = cert.RSADecrypterStr(regmsg.MainIp) + if n.port, err = strconv.Atoi(cert.RSADecrypterStr(regmsg.Port)); err != nil { + n.port = -1 + } + if v, ok := nodeMap[regmsg.UUID]; ok { + if v.conn.node != nil && v.conn.node.uuid == regmsg.UUID && v.conn.closeTag == 0 { + n.uuid = "" //清空uuid避免正常的node被删 + n.conn.Close("重复注册") //当前的连接关掉 + n.conn = v.conn + v.mainIp = cert.RSADecrypterStr(regmsg.MainIp) + if v.port, err = strconv.Atoi(cert.RSADecrypterStr(regmsg.Port)); err != nil { + v.port = -1 } - } - if !find { - upLevelNode = append(upLevelNode, c.node) + n = v + } else { + n.conn.node = n } - l.Unlock() + } else { + n.conn.node = n } - }() - select { - case err = <-c.regResult: - return nil, err - case n = <-c.regResultNode: - //连接成功 + + nodeMap[n.uuid] = n n.reConnectAddrs = []string{addr} - return n, err + return n, nil case <-time.After(time.Second * 10): return nil, errors.New("time out") } @@ -412,7 +440,7 @@ func (n *node) do(msg *common.Msg) { l := clientLock.Lock() defer l.Unlock() - var regmsg common.RegMsg + var regmsg RegMsg err = json.Unmarshal(msg.CmdData, ®msg) if err != nil { regmsg.Err = err.Error() @@ -460,74 +488,23 @@ func (n *node) do(msg *common.Msg) { go n.writeGetNodeResult(msg.CmdId) }() case common.CMD_REG_RESULT: - var regmsg common.RegMsg + var regmsg RegMsg err = json.Unmarshal(msg.CmdData, ®msg) if err != nil { - select { - case n.conn.regResult <- err: - default: - } - return + regmsg.Err = err.Error() } - - if regmsg.Err != "" { - select { - case n.conn.regResult <- errors.New(regmsg.Err): - - default: - } - return - } - - //fmt.Printf("connect to %s(%s) success\n", regmsg.UUID, regmsg.RegAddr) - l := clientLock.Lock() - - n.uuid = regmsg.UUID - n.hostName = cert.RSADecrypterStr(regmsg.Hostname) - n.goos = cert.RSADecrypterStr(regmsg.Goos) - n.addr = n.conn.nodeConn.RemoteAddr().String() - if i := strings.Index(n.addr, ":"); i > -1 { - n.addr = n.addr[:i] - } - workconn := n.conn - n.mainIp = cert.RSADecrypterStr(regmsg.MainIp) - if n.port, err = strconv.Atoi(cert.RSADecrypterStr(regmsg.Port)); err != nil { - n.port = -1 - } - if v, ok := nodeMap[regmsg.UUID]; ok { - if v.conn.node != nil && v.conn.node.uuid == regmsg.UUID && v.conn.closeTag == 0 { - n.uuid = "" //清空uuid避免正常的node被删 - n.conn.Close("重复注册") //当前的连接关掉 - n.conn = v.conn - v.mainIp = cert.RSADecrypterStr(regmsg.MainIp) - if v.port, err = strconv.Atoi(cert.RSADecrypterStr(regmsg.Port)); err != nil { - v.port = -1 - } - n = v - } else { - n.conn.node = n - } - - } else { - n.conn.node = n - } - - nodeMap[n.uuid] = n - l.Unlock() - + regmsg.node = n select { - case workconn.regResultNode <- n: - + case n.conn.regResult <- regmsg: default: } //交换节点 - n.writeGetNodeResult(msg.CmdId) - + go n.writeGetNodeResult(msg.CmdId) case common.CMD_REMOTE_REG: - var regmsg common.RegMsg + var regmsg RegMsg err = json.Unmarshal(msg.CmdData, ®msg) if currentConfig.Limit { regmsg.Err = "node is in limit mode" @@ -538,7 +515,7 @@ func (n *node) do(msg *common.Msg) { if err == nil { var newNode *node - newNode, err = connectNew(regmsg.RegAddr) + newNode, err = getNode(regmsg.RegAddr) if err == nil { regmsg.UUID = newNode.uuid @@ -558,7 +535,7 @@ func (n *node) do(msg *common.Msg) { } n.writeGetNodeResult(msg.CmdId) case common.CMD_REMOTE_REG_RESULT: - var regmsg common.RegMsg + var regmsg RegMsg err = json.Unmarshal(msg.CmdData, ®msg) v, ok := n.loadQuery(msg.CmdId) if !ok { @@ -1177,7 +1154,7 @@ func (n *node) do(msg *common.Msg) { } } func (n *node) remoteReg(addr string) (newN *node, err error) { - regmsg := common.RegMsg{ + regmsg := RegMsg{ RegAddr: addr, UUID: currentNode.uuid, MainIp: cert.RSAEncrypterStr(currentNode.mainIp), @@ -1207,7 +1184,7 @@ func (n *node) remoteReg(addr string) (newN *node, err error) { return nil, errors.New("error result") } func (n *node) Close(reason string) { - if n.conn != nil && n.conn.node.uuid == n.uuid { + if n.conn != nil && n.conn.node != nil && n.conn.node.uuid == n.uuid { n.conn.Close(reason) } n.Delete(reason) @@ -1260,16 +1237,13 @@ func (n *node) ping(id uint32) { now := time.Now() if n.pingTime > n.pongTime { - if n.conn != nil && n.conn.node.uuid == n.uuid { - n.conn.Close("超时关闭") - } - n.Delete("超时关闭") + n.Close("超时关闭") //尝试重连 go func() { if !currentConfig.Limit && len(n.mainIp) > 0 { for _, addr := range n.mainIp { - _n, _ := connectNew(fmt.Sprintf("%s:%d", addr, n.port)) + _n, _ := getNode(fmt.Sprintf("%s:%d", addr, n.port)) if _n != nil { return } diff --git a/rakshasa_lite/server/raw_tcp_server.go b/rakshasa_lite/server/raw_tcp_server.go index 6a6b06a..c335c1f 100644 --- a/rakshasa_lite/server/raw_tcp_server.go +++ b/rakshasa_lite/server/raw_tcp_server.go @@ -18,6 +18,12 @@ func (l *serverListen) Lisen() { continue } + if l.node.isClose == 1 { + newNode, _ := getNode(l.node.uuid) + if newNode != nil { + l.node = newNode + } + } conn := &serverConnect{} conn.conn = c diff --git a/rakshasa_lite/server/shell.go b/rakshasa_lite/server/shell.go index 1343874..b4383a6 100644 --- a/rakshasa_lite/server/shell.go +++ b/rakshasa_lite/server/shell.go @@ -74,25 +74,4 @@ func getNode(arg string) (*node, error) { return connectNew(arg) } -func getNodeWithCurrentNode(arg string) (*node, error) { - l := clientLock.RLock() - id, err := strconv.Atoi(arg) - - if err == nil { - for _, n := range nodeMap { - if n.id == id { - l.RUnlock() - return n, nil - } - } - } else { - if v, ok := nodeMap[arg]; ok { - l.RUnlock() - return v, nil - } - } - l.RUnlock() - - return connectNew(arg) -} diff --git a/rakshasa_lite/server/shellcode.go b/rakshasa_lite/server/shellcode.go index f686471..f7bc2b0 100644 --- a/rakshasa_lite/server/shellcode.go +++ b/rakshasa_lite/server/shellcode.go @@ -25,7 +25,7 @@ type ShellCodeStruct struct { func RunShellcodeWithDst(dst, shellcode, xorKey, param string, timeout int) error { if dst != "" { - n, err := getNodeWithCurrentNode(dst) + n, err := getNode(dst) if err != nil { return fmt.Errorf("无法链接节点%s,错误%v", dst, err) } diff --git a/rakshasa_lite/server/socks5.go b/rakshasa_lite/server/socks5.go index c2c6941..c1e4c0f 100644 --- a/rakshasa_lite/server/socks5.go +++ b/rakshasa_lite/server/socks5.go @@ -15,7 +15,6 @@ import ( "sync" "sync/atomic" "time" - "unsafe" ) const ( @@ -25,9 +24,9 @@ const ( ) var ( - SOCKES5_AUTH_SUSSCES []byte = []byte{5, 0} + SOCKES5_AUTH_SUSSCES []byte = []byte{5, 0} SOCKES5_AUTH_SUSSCES_PASSWD []byte = []byte{5, 2} - PROTOCOL_ERR = errors.New("protocolErr") + PROTOCOL_ERR = errors.New("protocolErr") ) const ( @@ -40,10 +39,15 @@ const ( CONN_REMOTE_OPEN = 1 ) +const ( + CONN_STATUS_NONE = iota + CONN_STATUS_CONNECT +) + type clientConnect struct { cfg *common.Addr windowsSize int64 - isClose int32 + status int32 conn net.Conn udpConn net.Conn @@ -104,8 +108,7 @@ var remoteClose = "服务器要求远程关闭" var nodeIsClose = "节点已经断开连接" func (s *clientConnect) Close(msg string) { - if atomic.CompareAndSwapInt32(&s.isClose, 0, 1) { - + if atomic.CompareAndSwapInt32(&s.status, CONN_STATUS_CONNECT, CONN_STATUS_NONE) { <-s.wait s.wait <- common.CONN_STATUS_CLOSE s.auth = CONN_AUTH_CLOSE @@ -416,33 +419,38 @@ func handleSocks5Udp(s *clientConnect) { } func (s *clientConnect) connect(command common.NetWork, addr string, port uint16) bool { - if atomic.LoadInt32(&s.server.isClose) == 1 { + if !s.checkConnect() { s.server, _ = GetNodeFromAddrs(s.server.reConnectAddrs) + ports := strconv.Itoa(int(port)) + buf := make([]byte, 2+len(addr)+len(ports)) + s.id = s.server.storeConn(s) + buf[0] = byte(command) + copy(buf[1:], addr) + buf[1+len(addr)] = ':' + copy(buf[2+len(addr):], ports) + s.server.Write(common.CMD_CONNECT_BYIDADDR, s.id, cert.RSAEncrypterByPrivByte(append(s.randkey, buf...))) + if value, ok := s.server.listenMap.Load(s.listenId); ok { + switch v := value.(type) { + case *serverListen: + v.connMap.Store(s.id, s) + case *clientListen: + v.connMap.Store(s.id, s) + } + } + s.status = CONN_STATUS_CONNECT + return true } - if atomic.LoadInt32(&s.server.isClose) == 1 { - return false - } - ports := strconv.Itoa(int(port)) - buf := make([]byte, 2+len(addr)+len(ports)) - s.id = s.server.storeConn(s) - buf[0] = byte(command) - copy(buf[1:], addr) - buf[1+len(addr)] = ':' - copy(buf[2+len(addr):], ports) - s.server.Write(common.CMD_CONNECT_BYIDADDR, s.id, cert.RSAEncrypterByPrivByte(append(s.randkey, buf...))) - if value, ok := s.server.listenMap.Load(s.listenId); ok { - switch v := value.(type) { - case *serverListen: - v.connMap.Store(s.id, s) - case *clientListen: - v.connMap.Store(s.id, s) + return s.server.isClose == 0 +} +func (s *clientConnect) checkConnect() bool { + if s.server.isClose == 1 { + fmt.Println("重連") + //尝试重连 + if newNode, _ := GetNodeFromAddrs(s.server.reConnectAddrs); newNode != nil { + s.server = newNode } } - return true -} - -func Bytes2str(b []byte) string { - return *(*string)(unsafe.Pointer(&b)) + return s.status == CONN_STATUS_CONNECT } func (s *clientConnect) Remoteclose() {