增加http_proxy重连逻辑
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"rakshasa/common"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
func CheckProxy(in, out string, timeout uint, checkurl string, anonymous bool) {
|
||||
outFile, err := os.OpenFile(out, os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0666)
|
||||
if err != nil {
|
||||
log.Fatalf("CheckProxy 无法写出文件 %s", out)
|
||||
}
|
||||
defer outFile.Close()
|
||||
var res int
|
||||
if cfg, err := common.ParseAddr(in); err == nil {
|
||||
if check(cfg, timeout, checkurl, outFile, anonymous) {
|
||||
res = 1
|
||||
}
|
||||
} else {
|
||||
inFile, err := os.OpenFile(in, os.O_RDONLY, 0666)
|
||||
if err != nil {
|
||||
log.Fatalf("-check_proxy 无法识别无法读取 %s", in)
|
||||
}
|
||||
limit := make(chan struct{}, 32)
|
||||
reader := bufio.NewReader(inFile)
|
||||
var wg sync.WaitGroup
|
||||
for {
|
||||
line, err := reader.ReadString(10)
|
||||
if err == io.EOF && line == "" {
|
||||
break
|
||||
}
|
||||
wg.Add(1)
|
||||
limit <- struct{}{}
|
||||
go func() {
|
||||
line = strings.TrimRight(line, "\n")
|
||||
line = strings.TrimRight(line, "\r")
|
||||
|
||||
if cfg, err = common.ParseAddr(line); err == nil {
|
||||
if check(cfg, timeout, checkurl, outFile, anonymous) {
|
||||
res++
|
||||
}
|
||||
}
|
||||
|
||||
<-limit
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
log.Printf("一共有%d个代理通过检测,已保存到 %v", res, out)
|
||||
|
||||
}
|
||||
func check(cfg *common.Addr, timeout uint, checkurl string, outFile *os.File, anonymous bool) bool {
|
||||
|
||||
switch cfg.Scheam() {
|
||||
case "", "http://":
|
||||
|
||||
proxy := func(_ *http.Request) (*url.URL, error) {
|
||||
return url.Parse(cfg.HttpUrl())
|
||||
}
|
||||
|
||||
transport := &http.Transport{Proxy: proxy}
|
||||
|
||||
client := &http.Client{Transport: transport, Timeout: time.Second * time.Duration(timeout)}
|
||||
resp, err := client.Get(checkurl)
|
||||
|
||||
if err != nil {
|
||||
|
||||
if strings.Contains(err.Error(), "Client.Timeout") {
|
||||
//log.Printf("地址 %v 检测失败 超时没响应\r\n", cfg)
|
||||
//} else {
|
||||
//log.Printf("地址 %v 检测失败 %v\r\n", cfg, err)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
if resp.StatusCode == 200 {
|
||||
if anonymous {
|
||||
b, _ := io.ReadAll(resp.Body)
|
||||
if string(b) == cfg.IP() {
|
||||
log.Printf("地址 %v 通过匿名代理检测\r\n", cfg.String())
|
||||
if _, err = outFile.WriteString(cfg.String() + "\r\n"); err != nil {
|
||||
log.Printf("无法写入文件%s", outFile.Name())
|
||||
}
|
||||
if err = outFile.Sync(); err != nil {
|
||||
log.Printf("无法写入文件%s", outFile.Name())
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
log.Printf("地址 %v 通过检测\r\n", cfg.String())
|
||||
if _, err = outFile.WriteString(cfg.String() + "\r\n"); err != nil {
|
||||
log.Printf("无法写入文件%s", outFile.Name())
|
||||
}
|
||||
if err = outFile.Sync(); err != nil {
|
||||
log.Printf("无法写入文件%s", outFile.Name())
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
//log.Printf("地址 %v 检测失败 结果状态码不是 200\r\n", addr)
|
||||
return false
|
||||
case "socks5://":
|
||||
|
||||
netconn, err := net.Dial("tcp", cfg.Addr())
|
||||
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
netconn.Write([]byte{5, 1, 2})
|
||||
var result [8192]byte
|
||||
n, err := netconn.Read(result[:])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if string(result[:n]) == string([]byte{5, 2}) { //需要认证
|
||||
user, password := cfg.User(), cfg.Password()
|
||||
if user == "" && password == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
data := make([]byte, (3 + len(user) + len(password)))
|
||||
data[0] = 5
|
||||
data[1] = byte(len(user))
|
||||
copy(data[2:], user)
|
||||
data[2+len(user)] = byte(len(password))
|
||||
copy(data[3+len(user):], password)
|
||||
netconn.Write(data)
|
||||
n, err = netconn.Read(result[:])
|
||||
if err != nil || string(result[:n]) != string([]byte{5, 0}) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
log.Printf("地址 %v 通过socks5检测\r\n", cfg.String())
|
||||
if _, err = outFile.WriteString(cfg.String() + "\r\n"); err != nil {
|
||||
log.Printf("无法写入文件%s", outFile.Name())
|
||||
}
|
||||
if err = outFile.Sync(); err != nil {
|
||||
log.Printf("无法写入文件%s", outFile.Name())
|
||||
}
|
||||
return true
|
||||
default:
|
||||
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
+18
-1
@@ -57,7 +57,7 @@ func cliInit() *ishell.Shell {
|
||||
return
|
||||
}
|
||||
for _, addr := range strings.Split(c.Args[0], ",") {
|
||||
_, err := connectNew(addr)
|
||||
_, err := getNode(addr)
|
||||
if err != nil {
|
||||
c.Println("连接", addr, "失败", err)
|
||||
return
|
||||
@@ -106,6 +106,23 @@ func cliInit() *ishell.Shell {
|
||||
|
||||
},
|
||||
})
|
||||
shell.AddCmd(&ishell.Cmd{
|
||||
Name: "closenode",
|
||||
Help: "关闭一个node ID",
|
||||
Func: func(c *ishell.Context) {
|
||||
l := clientLock.Lock()
|
||||
defer l.Unlock()
|
||||
if len(c.Args) != 1 {
|
||||
c.Println("参数不对")
|
||||
return
|
||||
}
|
||||
n, ok := nodeMap[c.Args[0]]
|
||||
if ok {
|
||||
n.Close("debug关闭")
|
||||
}
|
||||
|
||||
},
|
||||
})
|
||||
}
|
||||
return shell
|
||||
}
|
||||
|
||||
+9
-1
@@ -1,9 +1,11 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"gopkg.in/yaml.v3"
|
||||
"io/ioutil"
|
||||
"rakshasa/common"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
var currentConfig common.Config
|
||||
@@ -13,6 +15,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)
|
||||
|
||||
+8
-4
@@ -40,8 +40,7 @@ type Conn struct {
|
||||
close chan string
|
||||
isClient bool
|
||||
nodeConn *tls.Conn
|
||||
regResult chan error
|
||||
regResultNode chan *node
|
||||
regResult chan RegMsg
|
||||
}
|
||||
|
||||
type serverListen struct {
|
||||
@@ -544,7 +543,7 @@ func (c *Conn) handlerNodeRead() {
|
||||
}
|
||||
}
|
||||
case <-time.After(common.CMD_TIMEOUT):
|
||||
newNode.Delete("超时")
|
||||
newNode.Close("超时")
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -660,6 +659,7 @@ func (c *Conn) handle() {
|
||||
if common.Debug {
|
||||
fmt.Println(c.nodeConn.RemoteAddr().String(), "关闭原因", reason)
|
||||
}
|
||||
|
||||
if c.nodeConn != nil {
|
||||
if common.Debug {
|
||||
fmt.Println("執行close1")
|
||||
@@ -668,6 +668,7 @@ func (c *Conn) handle() {
|
||||
}
|
||||
|
||||
if c.node != nil {
|
||||
c.node.Close(reason)
|
||||
//移除上游连接
|
||||
for i := len(upLevelNode) - 1; i >= 0; i-- {
|
||||
n := upLevelNode[i]
|
||||
@@ -675,6 +676,9 @@ func (c *Conn) handle() {
|
||||
upLevelNode = append(upLevelNode[:i], upLevelNode[i+1:]...)
|
||||
}
|
||||
}
|
||||
if common.Debug {
|
||||
fmt.Println("upLevelNode",len(upLevelNode))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -690,7 +694,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)),
|
||||
|
||||
+98
-30
@@ -1,18 +1,20 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"cert"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash/crc32"
|
||||
"io"
|
||||
"log"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"cert"
|
||||
"rakshasa/common"
|
||||
"rakshasa/httppool"
|
||||
"runtime/debug"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -27,7 +29,7 @@ const CheckProxyUrl = "https://myip.fireflysoft.net/"
|
||||
|
||||
type httpProxyClient struct {
|
||||
windowsSize int64
|
||||
isclose int32
|
||||
status int32
|
||||
conn net.Conn
|
||||
udpconn net.Conn
|
||||
|
||||
@@ -40,10 +42,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
|
||||
@@ -68,7 +69,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"))
|
||||
}
|
||||
@@ -90,7 +93,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
|
||||
@@ -147,10 +150,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
|
||||
}
|
||||
@@ -183,7 +186,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
|
||||
@@ -280,20 +283,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
|
||||
@@ -303,7 +309,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
|
||||
}
|
||||
@@ -349,9 +357,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)
|
||||
@@ -365,7 +372,7 @@ func (s *httpProxyClient) connect() {
|
||||
buf = append(buf, []byte(" "+proxy.String())...)
|
||||
}
|
||||
|
||||
s.server.Write(common.CMD_CONNECT_BYIDADDR, s.id, cert.RSAEncrypterByPrivByte(append(s.randkey,buf...)))
|
||||
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:
|
||||
@@ -374,11 +381,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 = "本地要求远程关闭"
|
||||
@@ -388,7 +406,7 @@ func (s *httpProxyClient) Remoteclose() {
|
||||
buf[1] = byte(s.id >> 8)
|
||||
buf[2] = byte(s.id >> 16)
|
||||
buf[3] = byte(s.id >> 24)
|
||||
s.server.Write(common.CMD_DELETE_LISTENCONN_BYID, s.listenId, append(s.randkey,buf...))
|
||||
s.server.Write(common.CMD_DELETE_LISTENCONN_BYID, s.listenId, append(s.randkey, buf...))
|
||||
|
||||
}
|
||||
func init() {
|
||||
@@ -611,3 +629,53 @@ 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
|
||||
}
|
||||
+90
-111
@@ -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"
|
||||
@@ -82,12 +92,14 @@ func InitCurrentNode() {
|
||||
time.AfterFunc(time.Second*10, checkUpLevelNode)
|
||||
}
|
||||
func checkUpLevelNode() {
|
||||
|
||||
if len(currentConfig.DstNode) > 0 && len(upLevelNode) == 0 {
|
||||
|
||||
//尝试重新连接节点
|
||||
for _, addr := range currentConfig.DstNode {
|
||||
connectNew(addr)
|
||||
if common.Debug {
|
||||
fmt.Println("重新连接", addr)
|
||||
}
|
||||
getNode(addr)
|
||||
}
|
||||
if len(upLevelNode) == 0 {
|
||||
//尝试连接其他节点
|
||||
@@ -97,7 +109,7 @@ func checkUpLevelNode() {
|
||||
fmt.Println("连接extNodeIp", addr)
|
||||
}
|
||||
|
||||
connectNew(addr)
|
||||
getNode(addr)
|
||||
if len(upLevelNode) > 0 {
|
||||
return
|
||||
}
|
||||
@@ -109,16 +121,17 @@ func checkUpLevelNode() {
|
||||
|
||||
for _, n := range nodeMap {
|
||||
if n.uuid != currentNode.uuid {
|
||||
func() {
|
||||
|
||||
func() {
|
||||
l.RUnlock()
|
||||
defer clientLock.RLock(l)
|
||||
|
||||
if len(n.mainIp) == 0 {
|
||||
_, err := getNode(fmt.Sprintf("%s:%d", n.addr, n.port))
|
||||
if common.Debug {
|
||||
fmt.Println("连接n.addr", fmt.Sprintf("%s:%d", n.addr, n.port))
|
||||
fmt.Printf("连接n.addr %s 错误 %v \r\n", fmt.Sprintf("%s:%d", n.addr, n.port), err)
|
||||
}
|
||||
connectNew(fmt.Sprintf("%s:%d", n.addr, n.port))
|
||||
|
||||
}
|
||||
}()
|
||||
if len(upLevelNode) > 0 {
|
||||
@@ -202,16 +215,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 {
|
||||
@@ -230,7 +246,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 {
|
||||
@@ -253,34 +269,50 @@ 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")
|
||||
}
|
||||
@@ -426,7 +458,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()
|
||||
@@ -477,76 +509,21 @@ 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
|
||||
}
|
||||
if common.Debug {
|
||||
fmt.Printf("nodeMap3 %s %p \r\n", n.uuid, 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"
|
||||
@@ -557,7 +534,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
|
||||
@@ -577,7 +554,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 {
|
||||
@@ -1208,7 +1185,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),
|
||||
@@ -1238,7 +1215,10 @@ 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 common.Debug {
|
||||
fmt.Println("Close ", reason)
|
||||
}
|
||||
if n.conn != nil && n.conn.node != nil && n.conn.node.uuid == n.uuid {
|
||||
n.conn.Close(reason)
|
||||
}
|
||||
n.Delete(reason)
|
||||
@@ -1295,16 +1275,14 @@ func (n *node) ping(id uint32) {
|
||||
if common.Debug {
|
||||
fmt.Println(time.Now().Format("2006-01-02 15:04:05"), n.uuid, "超时")
|
||||
}
|
||||
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
|
||||
}
|
||||
@@ -1425,6 +1403,7 @@ func (n *node) broadcastNode() {
|
||||
}
|
||||
|
||||
func GetNodeFromAddrs(dst []string) (n *node, err error) {
|
||||
|
||||
if len(dst) == 0 {
|
||||
return nil, errors.New("参数错误,目标节点为空")
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -27,7 +33,7 @@ func (l *serverListen) Lisen() {
|
||||
|
||||
if l.isSocks5 {
|
||||
conn.id = l.id
|
||||
l.node.Write(common.CMD_CONNECT_BYIDADDR_RESULT, l.replayid, append(l.randkey,l.socks5Replay...))
|
||||
l.node.Write(common.CMD_CONNECT_BYIDADDR_RESULT, l.replayid, append(l.randkey, l.socks5Replay...))
|
||||
go conn.handTcpReceive()
|
||||
return
|
||||
}
|
||||
@@ -38,7 +44,7 @@ func (l *serverListen) Lisen() {
|
||||
b[1] = byte(conn.id >> 8)
|
||||
b[2] = byte(conn.id >> 16)
|
||||
b[3] = byte(conn.id >> 24)
|
||||
conn.node.Write(common.CMD_CONNECT_BYID, l.id, append(l.randkey,b...))
|
||||
conn.node.Write(common.CMD_CONNECT_BYID, l.id, append(l.randkey, b...))
|
||||
l.connMap.Store(conn.id, conn)
|
||||
go conn.handTcpReceive()
|
||||
|
||||
|
||||
+33
-34
@@ -16,6 +16,8 @@ import (
|
||||
"rakshasa/aes"
|
||||
"rakshasa/common"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
@@ -134,8 +136,8 @@ func init() {
|
||||
currentConfig.Port = port
|
||||
currentNode.port = port
|
||||
currentConfig.FileSave = false
|
||||
if err := StartServer(fmt.Sprintf(":%d", currentConfig.Port)); err != nil {
|
||||
c.Printf("启动节点失败 %v, 请重新修改监听端口",currentConfig.Port)
|
||||
if err := StartServer(fmt.Sprintf(":%d", currentConfig.Port)); err != nil {
|
||||
c.Printf("启动节点失败 %v, 请重新修改监听端口", currentConfig.Port)
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -179,7 +181,24 @@ func init() {
|
||||
currentConfig.FileSave = false
|
||||
},
|
||||
})
|
||||
configShell.AddCmd(&ishell.Cmd{
|
||||
Name: "uuid",
|
||||
Help: "修改本节点UUID设置,使用方法uuid 字串符",
|
||||
Func: func(c *ishell.Context) {
|
||||
if len(c.Args) != 1 {
|
||||
c.Println("参数错误")
|
||||
return
|
||||
}
|
||||
if id, err := uuid.Parse(c.Args[0]); err == nil {
|
||||
currentConfig.UUID = id.String()
|
||||
currentConfig.FileSave = false
|
||||
SetConfig(currentConfig)
|
||||
} else {
|
||||
c.Println("输入的uuid不是合法的uuid,建议使用xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
|
||||
}
|
||||
|
||||
},
|
||||
})
|
||||
rootCli.AddCmd(&ishell.Cmd{
|
||||
Name: "config",
|
||||
Help: "配置管理",
|
||||
@@ -553,7 +572,7 @@ func init() {
|
||||
return
|
||||
}
|
||||
for _, addr := range strings.Split(c.Args[0], ",") {
|
||||
_, err := connectNew(addr)
|
||||
_, err := getNode(addr)
|
||||
if err != nil {
|
||||
c.Println("连接", addr, "失败", err)
|
||||
return
|
||||
@@ -788,46 +807,26 @@ func printConn() {
|
||||
})
|
||||
}
|
||||
func getNode(arg string) (*node, error) {
|
||||
l := clientLock.RLock()
|
||||
|
||||
l := clientLock.Lock()
|
||||
defer l.Unlock()
|
||||
id, err := strconv.Atoi(arg)
|
||||
|
||||
if err == nil {
|
||||
for _, n := range nodeMap {
|
||||
if n.id == id && n.uuid != currentNode.uuid {
|
||||
l.RUnlock()
|
||||
if n.id == id {
|
||||
return n, nil
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if v, ok := nodeMap[arg]; ok && v.uuid != currentNode.uuid {
|
||||
l.RUnlock()
|
||||
return v, nil
|
||||
}
|
||||
}
|
||||
l.RUnlock()
|
||||
|
||||
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
|
||||
for _, node := range nodeMap {
|
||||
if fmt.Sprintf("%s:%d", node.mainIp, node.port) == arg {
|
||||
return node, nil
|
||||
} else if fmt.Sprintf("%s:%d", node.addr, node.port) == arg {
|
||||
return node, nil
|
||||
} else if node.uuid == arg {
|
||||
return node, nil
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if v, ok := nodeMap[arg]; ok {
|
||||
l.RUnlock()
|
||||
return v, nil
|
||||
}
|
||||
}
|
||||
l.RUnlock()
|
||||
|
||||
return connectNew(arg)
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1,6 +1,7 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"cert"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
@@ -10,7 +11,6 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"cert"
|
||||
"rakshasa/common"
|
||||
"strconv"
|
||||
"time"
|
||||
@@ -28,7 +28,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)
|
||||
}
|
||||
|
||||
+43
-35
@@ -17,7 +17,6 @@ import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/luyu6056/ishell"
|
||||
)
|
||||
@@ -29,9 +28,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 (
|
||||
@@ -44,10 +43,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
|
||||
|
||||
@@ -109,9 +113,9 @@ func (s *clientConnect) Write(b []byte) {
|
||||
|
||||
var remoteClose = "服务器要求远程关闭"
|
||||
var nodeIsClose = "节点已经断开连接"
|
||||
func (s *clientConnect) Close(msg string) {
|
||||
if atomic.CompareAndSwapInt32(&s.isClose, 0, 1) {
|
||||
|
||||
func (s *clientConnect) Close(msg string) {
|
||||
if atomic.CompareAndSwapInt32(&s.status, CONN_STATUS_CONNECT, CONN_STATUS_NONE) {
|
||||
<-s.wait
|
||||
s.wait <- common.CONN_STATUS_CLOSE
|
||||
s.auth = CONN_AUTH_CLOSE
|
||||
@@ -302,12 +306,12 @@ func handleSocks5Local(s *clientConnect) {
|
||||
switch common.NetWork(data[1]) {
|
||||
case common.SOCKS5_CMD_CONNECT:
|
||||
addr, port := socks5ReadAddr(data)
|
||||
if !s.connect(common.SOCKS5_CMD_CONNECT, addr, port){
|
||||
if !s.connect(common.SOCKS5_CMD_CONNECT, addr, port) {
|
||||
s.Close(nodeIsClose)
|
||||
}
|
||||
case common.SOCKS5_CMD_BIND:
|
||||
addr, port := socks5ReadAddr(data)
|
||||
if !s.connect(common.SOCKS5_CMD_BIND, addr, port){
|
||||
if !s.connect(common.SOCKS5_CMD_BIND, addr, port) {
|
||||
s.Close(nodeIsClose)
|
||||
}
|
||||
case common.SOCKS5_CMD_UDP:
|
||||
@@ -336,11 +340,11 @@ func handleSocks5Local(s *clientConnect) {
|
||||
ipb := ipToByte(localIP)
|
||||
addr, port := socks5ReadAddr(data)
|
||||
|
||||
if s.connect(common.SOCKS5_CMD_UDP, addr, port){
|
||||
if s.connect(common.SOCKS5_CMD_UDP, addr, port) {
|
||||
copy(repdata[4:], ipb)
|
||||
s.conn.Write(repdata)
|
||||
go handleSocks5Udp(s)
|
||||
}else{
|
||||
} else {
|
||||
s.Close(nodeIsClose)
|
||||
}
|
||||
default:
|
||||
@@ -401,7 +405,7 @@ func handleSocks5Udp(s *clientConnect) {
|
||||
if v, ok := s.udpMap.Load(ip); !ok {
|
||||
|
||||
udps := &clientConnect{
|
||||
server: s.server,
|
||||
server: s.server,
|
||||
randkey: s.randkey,
|
||||
}
|
||||
udps.udpConn = s.udpConn
|
||||
@@ -426,34 +430,38 @@ func handleSocks5Udp(s *clientConnect) {
|
||||
}
|
||||
|
||||
}
|
||||
func (s *clientConnect) connect(command common.NetWork, addr string, port uint16)bool {
|
||||
if atomic.LoadInt32(&s.server.isClose) == 1 {
|
||||
func (s *clientConnect) connect(command common.NetWork, addr string, port uint16) bool {
|
||||
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 {
|
||||
//尝试重连
|
||||
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() {
|
||||
|
||||
Reference in New Issue
Block a user