更新lite
This commit is contained in:
+33
-11
@@ -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()
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package common
|
||||
|
||||
type Config struct {
|
||||
UUID string //以指定uuid启动
|
||||
DstNode []string //-d 上级节点
|
||||
Password string //通讯密码,可为空
|
||||
Port int //默认8883
|
||||
|
||||
@@ -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
|
||||
}
|
||||
+10
-2
@@ -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:[email protected]: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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)),
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
+77
-103
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user