修复多节点连接的bug
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
+13
-3
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/dlclark/regexp2"
|
||||
"github.com/google/uuid"
|
||||
"math/rand"
|
||||
"net"
|
||||
@@ -15,6 +16,7 @@ import (
|
||||
)
|
||||
|
||||
var Debug bool = false
|
||||
var NoPing bool = false
|
||||
var DebugLock bool = false
|
||||
var DebugLockMap sync.Map
|
||||
|
||||
@@ -194,13 +196,12 @@ func init() {
|
||||
|
||||
type RegMsg struct {
|
||||
UUID string //当前机器uuid
|
||||
Addr string
|
||||
RegAddr string //远程连接的addr
|
||||
Hostname string //当前机器名称
|
||||
Goos string
|
||||
ViaUUID string
|
||||
Err string
|
||||
MainIp []string
|
||||
MainIp string
|
||||
Port int
|
||||
}
|
||||
|
||||
@@ -310,7 +311,16 @@ func ResolveTCPAddr(str string) ([]string, error) {
|
||||
dst = append(dst[:i], dst[i+1:]...)
|
||||
} else {
|
||||
if _, err := net.ResolveTCPAddr("tcp", addr); err != nil {
|
||||
return nil, fmt.Errorf("参数错误 格式为\"ip:端口\",多个地址以逗号隔开,错误详情%v", err)
|
||||
if i>0{
|
||||
r, _ := regexp2.Compile(`^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}`, 0)
|
||||
match,_ :=r.MatchString(addr)
|
||||
if !match{
|
||||
return nil, fmt.Errorf("参数错误 格式为\"ip:端口\",多个地址以逗号隔开,错误详情%v", err)
|
||||
}
|
||||
}else{
|
||||
return nil, fmt.Errorf("参数错误 格式为\"ip:端口,第二个地址可以是UUID\",多个地址以逗号隔开,错误详情%v", err)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ type Config struct {
|
||||
DstNode []string //-d 上级节点
|
||||
Password string //通讯密码,可为空
|
||||
Port int //默认8883
|
||||
ListenIp []string //指定公网ip,其他节点进行额外节点连接时候,尝试连接的ip
|
||||
ListenIp string //指定公网ip,其他节点进行额外节点连接时候,尝试连接的ip
|
||||
Limit bool //禁止额外连接,只连接-d节点,不会尝试连接其他节点
|
||||
FileName string
|
||||
FileSave bool `yaml:"-"`
|
||||
|
||||
@@ -8,194 +8,19 @@
|
||||
66.29.154.103:3128
|
||||
35.222.50.197:80
|
||||
169.55.89.6:80
|
||||
174.70.1.210:8080
|
||||
35.209.198.222:80
|
||||
208.109.32.60:81
|
||||
3.134.56.120:80
|
||||
20.241.236.196:3128
|
||||
216.215.123.174:8080
|
||||
3.128.142.113:80
|
||||
146.190.74.6:80
|
||||
24.106.221.230:53281
|
||||
165.3.122.211:80
|
||||
155.254.192.216:80
|
||||
104.255.231.87:3128
|
||||
45.61.163.12:80
|
||||
45.77.198.163:80
|
||||
216.137.184.253:80
|
||||
71.255.153.117:80
|
||||
104.223.135.178:10000
|
||||
109.122.195.16:80
|
||||
5.78.78.180:8080
|
||||
54.82.79.59:80
|
||||
52.24.80.166:80
|
||||
3.220.76.84:80
|
||||
129.153.107.221:80
|
||||
64.225.8.115:9997
|
||||
20.69.79.158:8443
|
||||
191.101.1.116:80
|
||||
5.78.75.64:8080
|
||||
72.169.67.145:87
|
||||
12.69.91.227:80
|
||||
4.16.68.158:443
|
||||
52.144.46.250:25345
|
||||
198.59.191.234:8080
|
||||
64.225.4.12:9991
|
||||
93.188.166.232:80
|
||||
137.184.197.190:80
|
||||
72.169.67.241:87
|
||||
130.41.109.158:8080
|
||||
204.2.218.145:8080
|
||||
66.75.121.167:8080
|
||||
162.223.94.163:80
|
||||
38.242.195.210:80
|
||||
64.225.8.132:9979
|
||||
93.188.161.84:80
|
||||
68.183.143.134:80
|
||||
64.225.8.142:9988
|
||||
184.60.66.122:80
|
||||
15.204.207.232:3128
|
||||
64.225.4.81:9991
|
||||
47.254.47.61:77
|
||||
64.225.8.118:9990
|
||||
31.220.52.49:80
|
||||
23.238.33.186:80
|
||||
52.86.21.254:80
|
||||
103.152.112.145:80
|
||||
3.12.178.169:80
|
||||
47.88.87.74:1080
|
||||
98.110.236.35:8080
|
||||
142.93.61.46:80
|
||||
154.202.97.224:3128
|
||||
154.201.62.199:3128
|
||||
154.202.122.29:3128
|
||||
154.202.98.115:3128
|
||||
72.169.66.157:87
|
||||
75.89.101.62:80
|
||||
64.225.8.121:9992
|
||||
198.11.175.192:3128
|
||||
159.89.132.167:8989
|
||||
72.170.220.17:8080
|
||||
148.76.97.250:80
|
||||
3.94.182.57:7497
|
||||
43.251.116.62:45787
|
||||
206.189.199.91:80
|
||||
34.23.45.223:80
|
||||
64.225.4.63:9998
|
||||
52.38.72.41:80
|
||||
38.52.220.194:999
|
||||
18.217.198.64:80
|
||||
206.161.97.62:31337
|
||||
170.187.138.40:8009
|
||||
143.198.182.218:80
|
||||
34.170.89.64:80
|
||||
97.74.92.60:80
|
||||
64.225.8.82:9995
|
||||
43.249.11.114:45787
|
||||
137.184.242.126:80
|
||||
143.110.232.177:80
|
||||
143.198.228.250:80
|
||||
209.126.6.159:80
|
||||
138.68.60.8:3128
|
||||
63.239.220.11:8080
|
||||
100.21.127.153:80
|
||||
34.229.213.84:8118
|
||||
45.81.130.51:45787
|
||||
198.199.86.11:8080
|
||||
108.161.128.43:80
|
||||
209.169.71.193:80
|
||||
64.225.8.191:9987
|
||||
167.99.236.14:80
|
||||
156.239.48.222:3128
|
||||
209.127.148.104:3128
|
||||
154.202.118.16:3128
|
||||
154.202.124.35:3128
|
||||
154.83.8.195:3128
|
||||
154.202.125.108:3128
|
||||
194.50.243.120:3128
|
||||
154.202.127.66:3128
|
||||
154.202.119.127:3128
|
||||
156.239.48.48:3128
|
||||
162.144.236.128:80
|
||||
157.230.48.102:80
|
||||
104.45.128.122:80
|
||||
149.248.14.12:24018
|
||||
72.169.67.85:87
|
||||
128.199.13.74:80
|
||||
64.225.4.29:9994
|
||||
72.52.217.188:80
|
||||
154.202.122.17:3128
|
||||
154.202.127.8:3128
|
||||
154.202.127.192:3128
|
||||
154.202.115.109:3128
|
||||
156.239.51.113:3128
|
||||
154.202.119.154:3128
|
||||
154.202.98.233:3128
|
||||
154.201.61.223:3128
|
||||
156.239.53.151:3128
|
||||
154.202.97.174:3128
|
||||
209.127.48.59:3128
|
||||
156.239.48.128:3128
|
||||
156.239.54.138:3128
|
||||
154.202.125.44:3128
|
||||
156.239.51.49:3128
|
||||
154.202.113.77:3128
|
||||
209.127.136.164:3128
|
||||
154.202.122.139:3128
|
||||
154.202.114.4:3128
|
||||
45.199.137.179:3128
|
||||
185.93.32.136:3128
|
||||
45.199.140.87:3128
|
||||
154.202.114.244:3128
|
||||
156.239.55.233:3128
|
||||
154.202.112.54:3128
|
||||
156.239.51.131:3128
|
||||
154.83.10.189:3128
|
||||
154.83.8.13:3128
|
||||
154.83.11.100:3128
|
||||
154.202.112.128:3128
|
||||
156.239.50.212:3128
|
||||
154.202.110.19:3128
|
||||
45.199.141.170:3128
|
||||
154.202.113.221:3128
|
||||
154.202.113.65:3128
|
||||
45.199.140.85:3128
|
||||
45.199.141.22:3128
|
||||
50.114.110.124:3128
|
||||
154.202.96.105:3128
|
||||
154.202.114.110:3128
|
||||
156.239.53.37:3128
|
||||
156.239.55.63:3128
|
||||
45.199.137.141:3128
|
||||
154.202.118.60:3128
|
||||
154.202.114.168:3128
|
||||
45.199.140.71:3128
|
||||
156.239.54.108:3128
|
||||
154.202.114.20:3128
|
||||
50.114.111.113:3128
|
||||
156.239.53.217:3128
|
||||
154.83.10.165:3128
|
||||
45.199.139.158:3128
|
||||
156.239.49.73:3128
|
||||
154.202.112.20:3128
|
||||
45.199.141.196:3128
|
||||
154.202.98.241:3128
|
||||
194.50.243.246:3128
|
||||
154.201.63.43:3128
|
||||
50.114.111.75:3128
|
||||
154.202.111.153:3128
|
||||
156.239.52.10:3128
|
||||
156.239.51.17:3128
|
||||
154.202.125.224:3128
|
||||
156.239.54.78:3128
|
||||
154.202.117.84:3128
|
||||
154.83.9.218:3128
|
||||
154.202.107.212:3128
|
||||
156.239.53.11:3128
|
||||
156.239.49.131:3128
|
||||
154.202.118.72:3128
|
||||
154.83.9.238:3128
|
||||
45.199.141.60:3128
|
||||
156.239.55.117:3128
|
||||
154.202.120.165:3128
|
||||
socks5://admin:[email protected]:1080
|
||||
167.71.246.128:3128
|
||||
129.21.158.30:8080
|
||||
69.167.174.17:80
|
||||
45.119.208.134:80
|
||||
216.21.18.194:80
|
||||
54.205.132.170:80
|
||||
113.121.39.200:7890
|
||||
54.222.237.192:8888
|
||||
120.27.239.26:7890
|
||||
47.92.110.4:7890
|
||||
183.230.162.122:9091
|
||||
35.232.243.222:80
|
||||
103.147.246.43:8080
|
||||
15.236.135.81:80
|
||||
186.96.2.89:999
|
||||
36.88.170.170:8080
|
||||
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
@@ -11,7 +12,6 @@ import (
|
||||
"rakshasa/httppool"
|
||||
"rakshasa/server"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
@@ -19,10 +19,10 @@ func main() {
|
||||
|
||||
var (
|
||||
//以下为配置参数
|
||||
dstNode = flag.String("d", "", "依次连接到指定的 上级节点地址,格式为 ip:端口 多个节点以,隔开\r\n -d 192.168.1.1:8883\r\n -d 192.168.1.1:8883,192.168.1.2:8882")
|
||||
dstNode = flag.String("d", "", "依次连接到指定的 上级节点地址,格式为 ip:端口 多个节点以,隔开 第二个地址可以是UUID\r\n -d 192.168.1.1:8883\r\n -d 192.168.1.1:8883,192.168.1.2:8882")
|
||||
limit = flag.String("limit", "", "limit模式,只连接-d的节点,不进行额外节点连接,默认为false,如果为true,本节点掉线的时候,将会尝试连接所有已保存节点")
|
||||
password = flag.String("password", "", "通讯二次加密秘钥,可为空")
|
||||
listenip = flag.String("ip", "", "设置本地节点指定公网ip,多个ip以,间隔,如\r\n -ip 192.168.1.1")
|
||||
listenip = flag.String("ip", "", "设置本地节点指定公网ip,如\r\n -ip 192.168.1.1")
|
||||
port = flag.String("p", "", "设置本地节点监听端口,默认8883")
|
||||
configFile = flag.String("f", "", "配置文件路径,为空的时候不读取")
|
||||
check_proxy = flag.String("check_proxy", "", "检查http代理是否有效,传入参数可以是ip:port 或者文件,当前支持ipv4,并将结果保存到-check_proxy_out,可选参数-check_proxy_timeout,-check_proxy_url,使用方法: \r\n -check_proxy 192.168.1.1:8080\r\n -check_proxy in.txt\r\n -check_proxy in.txt -check_proxy_out out.txt -check_proxy_timeout 10 -check_proxy_url https://www.google.com/")
|
||||
@@ -82,7 +82,7 @@ func main() {
|
||||
config.Password = *password
|
||||
}
|
||||
if *listenip != "" {
|
||||
config.ListenIp = strings.Split(*listenip, ",")
|
||||
config.ListenIp = *listenip
|
||||
}
|
||||
if *limit != "" {
|
||||
if *limit != "flase" && *limit != "true" {
|
||||
@@ -131,11 +131,9 @@ func main() {
|
||||
}
|
||||
|
||||
if *shellCode != "" {
|
||||
|
||||
server.RunShellcodeWithDst(*dstNode, *shellCode, *shellCodeXorKey, *shellCodeParam, *shellCodeTimeout)
|
||||
|
||||
}
|
||||
if err := server.StartServer(config.Port); err != nil {
|
||||
if err := server.StartServer(fmt.Sprintf("%s:%d", config.ListenIp, config.Port)); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
+18
-20
@@ -70,11 +70,11 @@ type serverConnect struct {
|
||||
}
|
||||
|
||||
// 中转与最终出口
|
||||
func StartServer(port int) error {
|
||||
func StartServer(addr string) error {
|
||||
config := cert.Tlsconfig.Clone()
|
||||
fmt.Println("start on port:", port)
|
||||
fmt.Println("start on ", addr)
|
||||
|
||||
l, err := tls.Listen("tcp", ":"+strconv.Itoa(port), config)
|
||||
l, err := tls.Listen("tcp", addr, config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("server start fail %v", err)
|
||||
}
|
||||
@@ -100,6 +100,7 @@ func StartServer(port int) error {
|
||||
go c.handle()
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
func init() {
|
||||
@@ -140,7 +141,6 @@ func (conn *serverConnect) Close(reason string) {
|
||||
}
|
||||
}
|
||||
func (c *Conn) Close(reason string) {
|
||||
|
||||
c.close <- reason
|
||||
|
||||
}
|
||||
@@ -493,7 +493,7 @@ func (c *Conn) handlerNodeRead() {
|
||||
b := aes.AesCtrDecrypt(buf)
|
||||
msg := common.UnmarshalMsg(b)
|
||||
if common.Debug {
|
||||
fmt.Println("fromto", msg.From, msg.To, common.CmdToName[msg.CmdOpteion])
|
||||
fmt.Println("fromto", msg.From, msg.To, common.CmdToName[msg.CmdOpteion], int(lengbuf[0])+int(lengbuf[1])<<8)
|
||||
}
|
||||
|
||||
if msg.To == common.NoneUUID.String() && c.node == nil {
|
||||
@@ -510,6 +510,7 @@ func (c *Conn) handlerNodeRead() {
|
||||
l.RUnlock()
|
||||
if ok && v.port > 0 {
|
||||
c.inChan <- func() {
|
||||
|
||||
v.do(msg)
|
||||
}
|
||||
} else {
|
||||
@@ -523,6 +524,9 @@ func (c *Conn) handlerNodeRead() {
|
||||
}
|
||||
result := make(chan interface{}, 1)
|
||||
id := newNode.storeQuery(result)
|
||||
if common.Debug {
|
||||
fmt.Printf("nodeMap1 %s %p \r\n", msg.From, newNode)
|
||||
}
|
||||
nodeMap[msg.From] = newNode
|
||||
l.Unlock()
|
||||
newNode.Write(common.CMD_GET_CURRENT_NODE, id, []byte{1}) //获取丢失节点的信息
|
||||
@@ -554,21 +558,17 @@ func (c *Conn) handlerNodeRead() {
|
||||
res = _v
|
||||
}
|
||||
|
||||
var nmsg nodeMsg
|
||||
var nmsg nodeInfo
|
||||
err = json.Unmarshal(msg.CmdData, &nmsg)
|
||||
if err != nil {
|
||||
res <- err
|
||||
return
|
||||
}
|
||||
|
||||
v.hostName = nmsg.HostName
|
||||
v.uuid = nmsg.UUID
|
||||
v.port = nmsg.Port
|
||||
v.mainIp = nmsg.MainIp
|
||||
v.goos = nmsg.Goos
|
||||
if nmsg.Addr != "" {
|
||||
v.addr = nmsg.Addr
|
||||
}
|
||||
res <- nil
|
||||
} else {
|
||||
v.waitMsg = append(v.waitMsg, msg)
|
||||
@@ -593,6 +593,10 @@ func (c *Conn) handlerNodeRead() {
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
if common.Debug {
|
||||
fmt.Println("广播do")
|
||||
}
|
||||
|
||||
newNode := &node{
|
||||
conn: c,
|
||||
}
|
||||
@@ -654,7 +658,9 @@ func (c *Conn) handle() {
|
||||
fmt.Println(c.nodeConn.RemoteAddr().String(), "关闭原因", reason)
|
||||
}
|
||||
if c.nodeConn != nil {
|
||||
|
||||
if common.Debug {
|
||||
fmt.Println("執行close1")
|
||||
}
|
||||
c.nodeConn.Close()
|
||||
}
|
||||
|
||||
@@ -680,10 +686,6 @@ func (c *Conn) handle() {
|
||||
}
|
||||
func (c *Conn) reg() error {
|
||||
|
||||
if c.nodeConn != nil {
|
||||
c.nodeConn.Close()
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
c.nodeConn, err = tls.Dial("tcp", c.nodeaddr, cert.Tlsconfig.Clone())
|
||||
@@ -693,7 +695,6 @@ func (c *Conn) reg() error {
|
||||
|
||||
reg := common.RegMsg{
|
||||
RegAddr: c.nodeaddr,
|
||||
Addr: currentNode.addr,
|
||||
UUID: currentNode.uuid,
|
||||
MainIp: currentNode.mainIp,
|
||||
Port: currentNode.port,
|
||||
@@ -732,10 +733,7 @@ func (c *Conn) Write(b []byte) {
|
||||
|
||||
func (c *Conn) tlsWrite(b []byte) error {
|
||||
c.nodeConn.SetWriteDeadline(time.Now().Add(common.WRITE_DEADLINE))
|
||||
n, err := c.nodeConn.Write(b)
|
||||
if common.Debug {
|
||||
fmt.Println("tlsWrite发送", n)
|
||||
}
|
||||
_, err := c.nodeConn.Write(b)
|
||||
if err != nil {
|
||||
c.Close("Write " + err.Error())
|
||||
upNodeWrite <- b
|
||||
|
||||
+169
-107
@@ -6,7 +6,6 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
uuid2 "github.com/google/uuid"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
@@ -15,12 +14,15 @@ import (
|
||||
"rakshasa/cert"
|
||||
"rakshasa/common"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
uuid2 "github.com/google/uuid"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -141,21 +143,18 @@ func nodeTickPing() {
|
||||
now := time.Now().Unix()
|
||||
for _, n := range nodeMap {
|
||||
if n.uuid != currentNode.uuid {
|
||||
for _, ip := range n.mainIp {
|
||||
if ip != "" {
|
||||
addr1 := fmt.Sprintf("%s:%d", ip, n.port)
|
||||
find := false
|
||||
for _, addr2 := range extNodeIp {
|
||||
if addr1 == addr2 {
|
||||
find = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !find {
|
||||
extNodeIp = append(extNodeIp, addr1)
|
||||
if n.mainIp != "" {
|
||||
addr1 := fmt.Sprintf("%s:%d", n.mainIp, n.port)
|
||||
find := false
|
||||
for _, addr2 := range extNodeIp {
|
||||
if addr1 == addr2 {
|
||||
find = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !find {
|
||||
extNodeIp = append(extNodeIp, addr1)
|
||||
}
|
||||
}
|
||||
if n.nextPingTime == 0 {
|
||||
go n.ping(0)
|
||||
@@ -185,7 +184,7 @@ type node struct {
|
||||
queryMap sync.Map
|
||||
conn *Conn
|
||||
pingTime, pongTime int64
|
||||
mainIp []string
|
||||
mainIp string
|
||||
port int
|
||||
listen net.Listener
|
||||
nextPingTime int64
|
||||
@@ -193,32 +192,70 @@ type node struct {
|
||||
waitMsg []*common.Msg //需要等待处理的消息
|
||||
mirrorNode *node //currentNode会生成一个互为mirror的node,以实现client-server功能,比如httpProxy在单节点启动
|
||||
}
|
||||
type nodeMsg struct {
|
||||
type nodeInfo struct {
|
||||
UUID string
|
||||
HostName string
|
||||
Addr string
|
||||
MainIp []string
|
||||
MainIp string
|
||||
Port int
|
||||
Goos string
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
config := cert.Tlsconfig.Clone()
|
||||
|
||||
conn, err := tls.Dial("tcp", addr, config)
|
||||
interfaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("无法获得网卡信息%v", err)
|
||||
}
|
||||
var connChan = make(chan *tls.Conn, 1)
|
||||
raddr, err := net.ResolveTCPAddr("tcp", addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, i := range interfaces {
|
||||
addrs, e := i.Addrs()
|
||||
if e == nil {
|
||||
for _, localAddr := range addrs {
|
||||
go func() {
|
||||
localstr := localAddr.String()
|
||||
localstr = localstr[:strings.LastIndex(localstr, "/")] + ":0"
|
||||
laddr, _ := net.ResolveTCPAddr("tcp", localstr)
|
||||
if netconn, e := net.DialTCP("tcp", laddr, raddr); e == nil {
|
||||
conn := tls.Client(netconn, config)
|
||||
select {
|
||||
case connChan <- conn:
|
||||
default:
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
}
|
||||
var conn *tls.Conn
|
||||
select {
|
||||
case c := <-connChan:
|
||||
conn = c
|
||||
case <-time.After(common.CMD_TIMEOUT):
|
||||
return nil, fmt.Errorf("无法连接%s", addr)
|
||||
}
|
||||
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.handle()
|
||||
c.reg()
|
||||
|
||||
defer func() {
|
||||
if c.node != nil {
|
||||
|
||||
l := clientLock.Lock()
|
||||
find := false
|
||||
for _, n := range upLevelNode {
|
||||
@@ -231,22 +268,6 @@ func connectNew(addr string) (n *node, e error) {
|
||||
}
|
||||
|
||||
l.Unlock()
|
||||
|
||||
resChan := make(chan interface{}, 1)
|
||||
id := c.node.storeQuery(resChan)
|
||||
|
||||
c.node.Write(common.CMD_GET_NODE, id, []byte{0})
|
||||
|
||||
select {
|
||||
case <-resChan:
|
||||
c.node.deleteQuery(id)
|
||||
c.node.broadcastNode()
|
||||
case <-time.After(common.CMD_TIMEOUT):
|
||||
c.node.deleteQuery(id)
|
||||
c.node.Close("")
|
||||
e = errors.New("time out")
|
||||
}
|
||||
|
||||
}
|
||||
}()
|
||||
select {
|
||||
@@ -268,11 +289,19 @@ func (n *node) Write(option uint8, id uint32, b []byte) {
|
||||
CmdId: id,
|
||||
CmdData: b,
|
||||
}
|
||||
|
||||
if n.uuid == currentNode.uuid {
|
||||
n.mirrorNode.do(&msg)
|
||||
} else {
|
||||
b := msg.Marshal()
|
||||
if common.Debug {
|
||||
fmt.Println("write", msg.From, msg.To, common.CmdToName[msg.CmdOpteion], len(b))
|
||||
}
|
||||
if len(b) == 195 {
|
||||
debug.PrintStack()
|
||||
}
|
||||
if n.conn != nil {
|
||||
n.conn.OutChan <- msg.Marshal()
|
||||
n.conn.OutChan <- b
|
||||
} else {
|
||||
upNodeWrite <- msg.Marshal()
|
||||
}
|
||||
@@ -280,6 +309,7 @@ func (n *node) Write(option uint8, id uint32, b []byte) {
|
||||
|
||||
}
|
||||
func (n *node) WriteMsg(msg *common.Msg) {
|
||||
|
||||
if n.conn != nil {
|
||||
n.conn.OutChan <- msg.Marshal()
|
||||
} else {
|
||||
@@ -402,14 +432,15 @@ func (n *node) do(msg *common.Msg) {
|
||||
return
|
||||
}
|
||||
|
||||
n.addr = regmsg.Addr
|
||||
n.hostName = regmsg.Hostname
|
||||
n.mainIp = regmsg.MainIp
|
||||
n.port = regmsg.Port
|
||||
n.goos = regmsg.Goos
|
||||
|
||||
n.addr = n.conn.nodeConn.RemoteAddr().String()
|
||||
if i := strings.Index(n.addr, ":"); i > -1 {
|
||||
n.addr = n.addr[:i]
|
||||
}
|
||||
resultMsg := regmsg
|
||||
resultMsg.Addr = currentNode.addr
|
||||
resultMsg.UUID = currentNode.uuid
|
||||
resultMsg.Hostname = currentNode.hostName
|
||||
resultMsg.MainIp = currentNode.mainIp
|
||||
@@ -423,10 +454,13 @@ func (n *node) do(msg *common.Msg) {
|
||||
n.uuid = uuid
|
||||
if v, ok := nodeMap[uuid]; !ok || v.conn.closeTag > 0 {
|
||||
n.conn.node = n
|
||||
if common.Debug {
|
||||
fmt.Printf("nodeMap2 %s %p \r\n", regmsg.UUID, n)
|
||||
}
|
||||
nodeMap[regmsg.UUID] = n
|
||||
n.broadcastNode()
|
||||
}
|
||||
|
||||
}
|
||||
currentNode.broadcastNode()
|
||||
}()
|
||||
case common.CMD_REG_RESULT:
|
||||
var regmsg common.RegMsg
|
||||
@@ -453,10 +487,12 @@ func (n *node) do(msg *common.Msg) {
|
||||
l := clientLock.Lock()
|
||||
|
||||
n.uuid = regmsg.UUID
|
||||
n.addr = regmsg.Addr
|
||||
n.hostName = regmsg.Hostname
|
||||
n.goos = 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 = regmsg.MainIp
|
||||
n.port = regmsg.Port
|
||||
@@ -475,6 +511,9 @@ func (n *node) do(msg *common.Msg) {
|
||||
} else {
|
||||
n.conn.node = n
|
||||
}
|
||||
if common.Debug {
|
||||
fmt.Printf("nodeMap3 %s %p \r\n", n.uuid, n)
|
||||
}
|
||||
nodeMap[n.uuid] = n
|
||||
l.Unlock()
|
||||
|
||||
@@ -485,7 +524,7 @@ func (n *node) do(msg *common.Msg) {
|
||||
}
|
||||
|
||||
//回复节点
|
||||
n.writeGetNodeResult(msg.CmdId)
|
||||
//n.writeGetNodeResult(msg.CmdId)
|
||||
|
||||
case common.CMD_REMOTE_REG:
|
||||
|
||||
@@ -498,16 +537,17 @@ func (n *node) do(msg *common.Msg) {
|
||||
return
|
||||
}
|
||||
if err == nil {
|
||||
var node *node
|
||||
node, err = connectNew(regmsg.RegAddr)
|
||||
var newNode *node
|
||||
|
||||
newNode, err = connectNew(regmsg.RegAddr)
|
||||
if err == nil {
|
||||
|
||||
regmsg.UUID = node.uuid
|
||||
regmsg.Hostname = node.hostName
|
||||
regmsg.UUID = newNode.uuid
|
||||
regmsg.Hostname = newNode.hostName
|
||||
regmsg.ViaUUID = currentNode.uuid
|
||||
regmsg.MainIp = currentNode.mainIp
|
||||
regmsg.Port = currentNode.port
|
||||
regmsg.Goos = currentNode.goos
|
||||
regmsg.MainIp = newNode.mainIp
|
||||
regmsg.Port = newNode.port
|
||||
regmsg.Goos = newNode.goos
|
||||
b, _ := json.Marshal(regmsg)
|
||||
n.Write(common.CMD_REMOTE_REG_RESULT, msg.CmdId, b)
|
||||
}
|
||||
@@ -517,6 +557,7 @@ func (n *node) do(msg *common.Msg) {
|
||||
b, _ := json.Marshal(regmsg)
|
||||
n.Write(common.CMD_REMOTE_REG_RESULT, msg.CmdId, b)
|
||||
}
|
||||
n.writeGetNodeResult(msg.CmdId)
|
||||
case common.CMD_REMOTE_REG_RESULT:
|
||||
var regmsg common.RegMsg
|
||||
err = json.Unmarshal(msg.CmdData, ®msg)
|
||||
@@ -533,41 +574,51 @@ func (n *node) do(msg *common.Msg) {
|
||||
return
|
||||
}
|
||||
l := clientLock.Lock()
|
||||
|
||||
n.uuid = regmsg.UUID
|
||||
n.addr = regmsg.Addr
|
||||
n.hostName = regmsg.Hostname
|
||||
n.goos = regmsg.Goos
|
||||
n.mainIp = regmsg.MainIp
|
||||
n.port = regmsg.Port
|
||||
if v, ok := nodeMap[regmsg.UUID]; !ok {
|
||||
n.conn.node = n
|
||||
} else {
|
||||
if v.conn.node.uuid == regmsg.UUID && v.conn.closeTag == 0 {
|
||||
n.conn.close <- "" //当前的连接关掉
|
||||
n.conn = v.conn
|
||||
v.mainIp = regmsg.MainIp
|
||||
v.port = regmsg.Port
|
||||
if n.uuid != regmsg.UUID {
|
||||
var targetNode *node
|
||||
if targetNode, ok = nodeMap[regmsg.UUID]; !ok {
|
||||
targetNode = getNewNode(nodeInfo{
|
||||
UUID: regmsg.UUID,
|
||||
HostName: regmsg.Hostname,
|
||||
MainIp: regmsg.MainIp,
|
||||
Port: regmsg.Port,
|
||||
Goos: regmsg.Goos,
|
||||
}, n)
|
||||
if common.Debug {
|
||||
fmt.Printf("nodeMap4 %s %p \r\n", regmsg.UUID, n)
|
||||
}
|
||||
nodeMap[regmsg.UUID] = targetNode
|
||||
} else {
|
||||
n.conn.node = n
|
||||
targetNode.updateNode(nodeInfo{
|
||||
UUID: regmsg.UUID,
|
||||
HostName: regmsg.Hostname,
|
||||
MainIp: regmsg.MainIp,
|
||||
Port: regmsg.Port,
|
||||
Goos: regmsg.Goos,
|
||||
})
|
||||
}
|
||||
|
||||
v <- targetNode
|
||||
} else {
|
||||
v <- n
|
||||
}
|
||||
nodeMap[n.uuid] = n
|
||||
|
||||
l.Unlock()
|
||||
//fmt.Printf("connect to %s(%s) success\n", regmsg.UUID, regmsg.RegAddr)
|
||||
n.writeGetNodeResult(msg.CmdId)
|
||||
n.broadcastNode()
|
||||
//n.writeGetNodeResult(msg.CmdId)
|
||||
|
||||
case common.CMD_PING:
|
||||
n.Write(common.CMD_PONG, msg.CmdId, msg.CmdData)
|
||||
n.Write(common.CMD_PONG, msg.CmdId, append(msg.CmdData, n.conn.nodeConn.LocalAddr().String()...))
|
||||
case common.CMD_NONE:
|
||||
|
||||
case common.CMD_PONG:
|
||||
pingTime := int64(msg.CmdData[0]) | int64(msg.CmdData[1])<<8 | int64(msg.CmdData[2])<<16 | int64(msg.CmdData[3])<<24 | int64(msg.CmdData[4])<<32 | int64(msg.CmdData[5])<<40 | int64(msg.CmdData[6])<<48 | int64(msg.CmdData[7])<<56
|
||||
|
||||
if pingTime != n.pingTime {
|
||||
return
|
||||
}
|
||||
n.addr = string(msg.CmdData[8:])
|
||||
if i := strings.Index(n.addr, ":"); i > -1 {
|
||||
n.addr = n.addr[:i]
|
||||
}
|
||||
n.pongTime = time.Now().Unix()
|
||||
if v, ok := n.loadQuery(msg.CmdId); ok {
|
||||
select {
|
||||
@@ -713,24 +764,20 @@ func (n *node) do(msg *common.Msg) {
|
||||
l := clientLock.Lock()
|
||||
defer l.Unlock()
|
||||
|
||||
var s []nodeMsg
|
||||
var s []nodeInfo
|
||||
err = json.Unmarshal(msg.CmdData, &s)
|
||||
if err == nil {
|
||||
for _, _n := range s {
|
||||
if _n.UUID != currentNode.uuid {
|
||||
if v, ok := nodeMap[_n.UUID]; !ok {
|
||||
nodeMap[_n.UUID] = newNode(_n, n)
|
||||
nodeMap[_n.UUID] = getNewNode(_n, n)
|
||||
} else {
|
||||
v.hostName = _n.HostName
|
||||
v.mainIp = _n.MainIp
|
||||
v.port = _n.Port
|
||||
if _n.Addr != "" {
|
||||
v.addr = _n.Addr
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
v, ok := n.loadQuery(msg.CmdId)
|
||||
@@ -742,10 +789,9 @@ func (n *node) do(msg *common.Msg) {
|
||||
}
|
||||
}
|
||||
case common.CMD_GET_CURRENT_NODE:
|
||||
nmsg := nodeMsg{
|
||||
nmsg := nodeInfo{
|
||||
UUID: currentNode.uuid,
|
||||
HostName: currentNode.hostName,
|
||||
Addr: currentNode.addr,
|
||||
MainIp: currentNode.mainIp,
|
||||
Port: currentNode.port,
|
||||
Goos: currentNode.goos,
|
||||
@@ -754,7 +800,7 @@ func (n *node) do(msg *common.Msg) {
|
||||
n.Write(common.CMD_GET_CURRENT_NODE_RESULT, msg.CmdId, b)
|
||||
|
||||
case common.CMD_ADD_NODE:
|
||||
var nmsg nodeMsg
|
||||
var nmsg nodeInfo
|
||||
err = json.Unmarshal(msg.CmdData, &nmsg)
|
||||
|
||||
if err != nil {
|
||||
@@ -763,20 +809,26 @@ func (n *node) do(msg *common.Msg) {
|
||||
|
||||
l := clientLock.Lock()
|
||||
defer l.Unlock()
|
||||
|
||||
if v, ok := nodeMap[nmsg.UUID]; !ok {
|
||||
newNode := getNewNode(nmsg, n)
|
||||
if common.Debug {
|
||||
fmt.Printf("nodeMap5 %s %p \r\n", nmsg.UUID, newNode)
|
||||
}
|
||||
|
||||
_n := newNode(nmsg, n)
|
||||
nodeMap[nmsg.UUID] = _n
|
||||
|
||||
nodeMap[nmsg.UUID] = newNode
|
||||
} else if nmsg.UUID != currentNode.uuid {
|
||||
|
||||
v.port = nmsg.Port
|
||||
v.mainIp = nmsg.MainIp
|
||||
v.hostName = nmsg.HostName
|
||||
v.goos = nmsg.Goos
|
||||
if nmsg.Addr != "" {
|
||||
v.addr = nmsg.Addr
|
||||
v.uuid = nmsg.UUID
|
||||
if common.Debug {
|
||||
fmt.Printf("nodeMap6 %s %p \r\n", nmsg.UUID, v)
|
||||
}
|
||||
|
||||
nodeMap[nmsg.UUID] = v
|
||||
|
||||
}
|
||||
case common.CMD_DIR:
|
||||
|
||||
@@ -1088,7 +1140,6 @@ func (n *node) do(msg *common.Msg) {
|
||||
}
|
||||
func (n *node) remoteReg(addr string) (newN *node, err error) {
|
||||
regmsg := common.RegMsg{
|
||||
Addr: currentNode.addr,
|
||||
RegAddr: addr,
|
||||
UUID: currentNode.uuid,
|
||||
MainIp: currentNode.mainIp,
|
||||
@@ -1099,6 +1150,7 @@ func (n *node) remoteReg(addr string) (newN *node, err error) {
|
||||
b, _ := json.Marshal(regmsg)
|
||||
resChan := make(chan interface{}, 1)
|
||||
id := n.storeQuery(resChan)
|
||||
|
||||
n.Write(common.CMD_REMOTE_REG, id, b)
|
||||
select {
|
||||
case i := <-resChan:
|
||||
@@ -1118,15 +1170,14 @@ func (n *node) remoteReg(addr string) (newN *node, err error) {
|
||||
}
|
||||
func (n *node) Close(reason string) {
|
||||
if n.conn != nil && n.conn.node.uuid == n.uuid {
|
||||
n.conn.close <- reason
|
||||
n.conn.Close(reason)
|
||||
}
|
||||
n.Delete(reason)
|
||||
}
|
||||
func newNode(m nodeMsg, n *node) *node {
|
||||
_n := &node{
|
||||
func getNewNode(m nodeInfo, n *node) *node {
|
||||
newNode := &node{
|
||||
uuid: m.UUID,
|
||||
hostName: m.HostName,
|
||||
addr: m.Addr,
|
||||
conn: n.conn,
|
||||
pongTime: time.Now().Unix(),
|
||||
mainIp: m.MainIp,
|
||||
@@ -1134,7 +1185,7 @@ func newNode(m nodeMsg, n *node) *node {
|
||||
goos: m.Goos,
|
||||
}
|
||||
|
||||
return _n
|
||||
return newNode
|
||||
}
|
||||
func allNodesDo(f func(*node) (bool, error)) (err error) {
|
||||
var ok bool
|
||||
@@ -1161,7 +1212,9 @@ func allNodesDo(f func(*node) (bool, error)) (err error) {
|
||||
return nil
|
||||
}
|
||||
func (n *node) ping(id uint32) {
|
||||
|
||||
if common.NoPing {
|
||||
return
|
||||
}
|
||||
l := clientLock.Lock()
|
||||
|
||||
defer func() {
|
||||
@@ -1270,20 +1323,22 @@ func (n *node) Delete(reason string) {
|
||||
|
||||
}
|
||||
func (n *node) broadcastNode() {
|
||||
|
||||
//广播新增节点
|
||||
nmsg := nodeMsg{
|
||||
nmsg := nodeInfo{
|
||||
UUID: n.uuid,
|
||||
HostName: n.hostName,
|
||||
Addr: n.addr,
|
||||
MainIp: n.mainIp,
|
||||
Port: n.port,
|
||||
Goos: n.goos,
|
||||
}
|
||||
|
||||
b, _ := json.Marshal(nmsg)
|
||||
writemsg := &common.Msg{
|
||||
From: currentNode.uuid,
|
||||
To: common.BroadcastUUID.String(),
|
||||
CmdData: append([]byte{common.CMD_ADD_NODE, 0, 0}, b...),
|
||||
From: currentNode.uuid,
|
||||
To: common.BroadcastUUID.String(),
|
||||
CmdOpteion: common.CMD_ADD_NODE,
|
||||
CmdData: b,
|
||||
}
|
||||
go allNodesDo(func(_n *node) (bool, error) {
|
||||
|
||||
@@ -1293,6 +1348,7 @@ func (n *node) broadcastNode() {
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func GetNodeFromAddrs(dst []string) (n *node, err error) {
|
||||
@@ -1306,7 +1362,7 @@ func GetNodeFromAddrs(dst []string) (n *node, err error) {
|
||||
for i := 1; i < len(dst); i++ {
|
||||
n, err = n.remoteReg(dst[i])
|
||||
if err != nil {
|
||||
return
|
||||
return nil, fmt.Errorf("%s,%v", dst[i], err)
|
||||
}
|
||||
}
|
||||
if n == nil {
|
||||
@@ -1353,19 +1409,19 @@ func (n *node) storeConn(v common.Conn) (newID uint32) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (n *node) writeGetNodeResult(id uint32) {
|
||||
l := clientLock.RLock()
|
||||
|
||||
defer l.RUnlock()
|
||||
|
||||
var s []nodeMsg
|
||||
var s []nodeInfo
|
||||
|
||||
for _, _n := range nodeMap {
|
||||
if _n.uuid != currentNode.uuid {
|
||||
s = append(s, nodeMsg{
|
||||
s = append(s, nodeInfo{
|
||||
UUID: _n.uuid,
|
||||
HostName: _n.hostName,
|
||||
Addr: _n.addr,
|
||||
MainIp: _n.mainIp,
|
||||
Port: _n.port,
|
||||
Goos: _n.goos,
|
||||
@@ -1377,3 +1433,9 @@ func (n *node) writeGetNodeResult(id uint32) {
|
||||
b, _ := json.Marshal(s)
|
||||
n.Write(common.CMD_GET_NODE_RESULT, id, b)
|
||||
}
|
||||
func (n *node) updateNode(msg nodeInfo) {
|
||||
n.hostName = msg.HostName
|
||||
n.mainIp = msg.MainIp
|
||||
n.port = msg.Port
|
||||
n.goos = msg.Goos
|
||||
}
|
||||
|
||||
+5
-12
@@ -133,24 +133,23 @@ func init() {
|
||||
currentConfig.Port = port
|
||||
currentNode.port = port
|
||||
currentConfig.FileSave = false
|
||||
currentNode.broadcastNode()
|
||||
StartServer(port)
|
||||
StartServer(fmt.Sprintf("%s:%d",currentConfig.ListenIp,currentConfig.Port))
|
||||
},
|
||||
})
|
||||
|
||||
configShell.AddCmd(&ishell.Cmd{
|
||||
Name: "ip",
|
||||
Help: "修改本节点连接ip,当其他节点进行额外连接时候,优先使用此ip连接, 多个ip以,隔开",
|
||||
Help: "修改本节点连接ip,当其他节点进行额外连接时候,优先使用此ip连接",
|
||||
Func: func(c *ishell.Context) {
|
||||
if len(c.Args) != 1 {
|
||||
c.Println("参数错误")
|
||||
return
|
||||
}
|
||||
|
||||
currentConfig.ListenIp = strings.Split(c.Args[0], ",")
|
||||
currentConfig.ListenIp = c.Args[0]
|
||||
currentNode.mainIp = currentConfig.ListenIp
|
||||
currentConfig.FileSave = false
|
||||
currentNode.broadcastNode()
|
||||
|
||||
},
|
||||
})
|
||||
configShell.AddCmd(&ishell.Cmd{
|
||||
@@ -752,13 +751,7 @@ func printNodes(c *ishell.Context) {
|
||||
copy(ip, n.addr+":"+strconv.Itoa(n.port))
|
||||
}
|
||||
|
||||
var s []string
|
||||
for _, ip := range n.mainIp {
|
||||
if ip != "" {
|
||||
s = append(s, ip+":"+strconv.Itoa(n.port))
|
||||
}
|
||||
}
|
||||
listenip := strings.Join(s, ",")
|
||||
listenip := n.mainIp
|
||||
goos := bytes.Repeat([]byte(" "), 11)
|
||||
copy(goos, n.goos)
|
||||
c.Printf("%2d %s %s %s %s %s\n", n.id, n.uuid, hostname, goos, ip, listenip)
|
||||
|
||||
Reference in New Issue
Block a user