解决直连成功后会自动断开的问题

This commit is contained in:
kony
2025-01-16 17:06:35 +08:00
parent 25fc3efe3e
commit 8c8a3c8fbd
4 changed files with 124 additions and 82 deletions

View File

@@ -18,8 +18,6 @@ var (
m_redis_db *redis.Client
m_tun_key string
m_md5_tun_key string
m_tun_active *tun.TunActive
m_tun_passive *tun.TunPassive
)
func Init(m_cli_redis_addr, m_cli_redis_pass string, m_cli_redis_id int) error {
@@ -53,22 +51,17 @@ func Init(m_cli_redis_addr, m_cli_redis_pass string, m_cli_redis_id int) error {
return errors.New("Redis失败, 请重启程序")
}
m_tun_active = nil
m_tun_passive = nil
return nil
}
func Release() {
func Release(tun_active *tun.TunActive, tun_passive *tun.TunPassive) {
utils.Log().SetDebugSate(0)
if m_tun_active != nil {
m_tun_active.Release()
m_tun_active = nil
if tun_active != nil {
tun_active.Release()
}
if m_tun_passive != nil {
m_tun_passive.Release()
m_tun_passive = nil
if tun_passive != nil {
tun_passive.Release()
}
}

View File

@@ -8,6 +8,7 @@ import (
"goodlink/utils"
"goodlink2/tun"
_ "goodlink2/tun"
"log"
"net"
"strings"
"time"
@@ -19,7 +20,10 @@ var (
m_local_state = 0 //0: 停止, 1: 启动, 2: 连接成功
)
func GetLocalQuicConn(conn_type int, count int) (quic.Connection, quic.Stream, error) {
func GetLocalQuicConn(conn_type int, count int) (*tun.TunActive, *tun.TunPassive, quic.Connection, quic.Stream, error) {
var tun_active *tun.TunActive
var tun_passive *tun.TunPassive
redisJson := RedisJsonType{
ConnectCount: count,
}
@@ -51,15 +55,15 @@ func GetLocalQuicConn(conn_type int, count int) (quic.Connection, quic.Stream, e
time.Sleep(1 * time.Second)
if RedisGet(&redisJson) != nil {
utils.Log().Debug("会话超时")
return nil, nil, nil
log.Println("会话超时")
return nil, nil, nil, nil, nil
}
utils.Log().SetDebugSate(redisJson.State)
if !strings.EqualFold(redisJson.SessionID, SessionID) {
utils.Log().Debug("会话被重置")
return nil, nil, nil
return nil, nil, nil, nil, nil
}
switch redisJson.State {
@@ -68,76 +72,81 @@ func GetLocalQuicConn(conn_type int, count int) (quic.Connection, quic.Stream, e
switch conn_type {
case 0:
if m_tun_passive != nil {
m_tun_passive.Release()
if tun_passive != nil {
tun_passive.Release()
}
m_tun_active = nil
tun_active = nil
redisJson.LocalIP, redisJson.LocalPort1, redisJson.LocalPort2 = LocalIP, LocalPort1, LocalPort2
if redisJson.LocalIP == redisJson.RemoteIP {
RedisDel()
return nil, nil, fmt.Errorf("已经和对端处在同一个公网下")
return nil, nil, nil, nil, fmt.Errorf("已经和对端处在同一个公网下")
}
m_tun_passive = tun.CteateTunPassive([]byte(redisJson.SessionID), conn, redisJson.RemoteIP, redisJson.RemotePort1, redisJson.RemotePort2, redisJson.SendPortCount)
m_tun_passive.Start()
tun_passive = tun.CteateTunPassive([]byte(redisJson.SessionID), conn, redisJson.RemoteIP, redisJson.RemotePort1, redisJson.RemotePort2, redisJson.SendPortCount)
tun_passive.Start()
redisJson.State = 2
utils.Log().DebugF("发送本端地址: %v", redisJson)
RedisSet(redisJson.RedisTimeOut, &redisJson)
default:
if m_tun_active != nil {
m_tun_active.Release()
if tun_active != nil {
tun_active.Release()
}
m_tun_passive = nil
tun_passive = nil
if redisJson.LocalIP == redisJson.RemoteIP {
RedisDel()
return nil, nil, fmt.Errorf("已经和对端处在同一个公网下")
return nil, nil, nil, nil, fmt.Errorf("已经和对端处在同一个公网下")
}
m_tun_active = tun.CreateTunActive([]byte(redisJson.SessionID), conn, 15*time.Second)
m_tun_active.Start(redisJson.LocalPort1, redisJson.LocalPort2, redisJson.RemoteIP, redisJson.RemotePort1, redisJson.RemotePort2, redisJson.SocketTimeOut)
tun_active = tun.CreateTunActive([]byte(redisJson.SessionID), conn, 15*time.Second)
tun_active.Start(redisJson.LocalPort1, redisJson.LocalPort2, redisJson.RemoteIP, redisJson.RemotePort1, redisJson.RemotePort2, redisJson.SocketTimeOut)
redisJson.State = 2
RedisSet(redisJson.RedisTimeOut, &redisJson)
}
case 3:
if m_tun_passive != nil {
if m_tun_passive.TunQuicConn != nil {
if tun_passive != nil {
if tun_passive.TunQuicConn != nil {
utils.Log().DebugF("连接成功")
return m_tun_passive.TunQuicConn, m_tun_passive.TunHealthStream, nil
return nil, tun_passive, tun_passive.TunQuicConn, tun_passive.TunHealthStream, nil
}
}
if m_tun_active != nil {
if m_tun_active.TunQuicConn != nil {
if tun_active != nil {
if tun_active.TunQuicConn != nil {
utils.Log().DebugF("连接成功")
return m_tun_active.TunQuicConn, m_tun_active.TunHealthStream, nil
return tun_active, nil, tun_active.TunQuicConn, tun_active.TunHealthStream, nil
}
}
utils.Log().Debug("连接失败")
return nil, nil, nil
return nil, nil, nil, nil, nil
case 4:
utils.Log().Debug("连接超时")
return nil, nil, nil
return nil, nil, nil, nil, nil
default:
utils.Log().Debug("等待对端状态")
}
}
return nil, nil, nil
return nil, nil, nil, nil, nil
}
func GetLocalStats() int {
return m_local_state
}
var (
m_tun_active *tun.TunActive
m_tun_passive *tun.TunPassive
)
func StopLocal() error {
m_local_state = 0
Release()
Release(m_tun_active, m_tun_passive)
return nil
}
@@ -166,16 +175,19 @@ func RunLocal(conn_type int, tun_local_addr string, tun_key string) error {
count++
conn, health, err := GetLocalQuicConn(conn_type, count)
tun_active, tun_passive, conn, health, err := GetLocalQuicConn(conn_type, count)
if err != nil {
Release()
Release(tun_active, tun_passive)
return err
}
if conn == nil {
Release()
Release(tun_active, tun_passive)
continue
}
m_tun_active = tun_active
m_tun_passive = tun_passive
go func() {
proxy.ProcessProxyClient(listener, conn)
chain <- 1
@@ -187,7 +199,7 @@ func RunLocal(conn_type int, tun_local_addr string, tun_key string) error {
m_local_state = 1
}
utils.Log().DebugF("释放连接: %v", conn.LocalAddr())
Release()
Release(tun_active, tun_passive)
if conn, err := net.Dial("tcp", tun_local_addr); conn != nil && err == nil {
conn.Write([]byte("hello"))

View File

@@ -8,6 +8,7 @@ import (
"goodlink/utils"
"goodlink2/tun"
_ "goodlink2/tun"
"log"
"net"
"strings"
"sync"
@@ -20,7 +21,10 @@ var (
m_remote_stats int
)
func GetRemoteQuicConn(time_out time.Duration) (quic.Connection, quic.Stream) {
func GetRemoteQuicConn(time_out time.Duration) (*tun.TunActive, *tun.TunPassive, quic.Connection, quic.Stream) {
var tun_active *tun.TunActive
var tun_passive *tun.TunPassive
redisJson := RedisJsonType{}
last_state := redisJson.State
conn_type := 0 //主动连接
@@ -33,33 +37,33 @@ func GetRemoteQuicConn(time_out time.Duration) (quic.Connection, quic.Stream) {
}
SessionID := redisJson.SessionID
utils.Log().DebugF("会话ID: %s", SessionID)
log.Printf("会话ID: %s", SessionID)
for m_remote_stats == 1 {
time.Sleep(1 * time.Second)
if RedisGet(&redisJson) != nil {
utils.Log().Debug("会话超时")
return nil, nil
log.Println("会话超时")
return nil, nil, nil, nil
}
utils.Log().SetDebugSate(redisJson.State)
if !strings.EqualFold(redisJson.SessionID, SessionID) {
utils.Log().Debug("会话被重置")
return nil, nil
return nil, nil, nil, nil
}
if redisJson.State < last_state {
m_redis_db.Del(m_md5_tun_key)
utils.Log().DebugF("状态异常: %d -> %d", last_state, redisJson.State)
return nil, nil
return nil, nil, nil, nil
}
if redisJson.State != 3 && redisJson.State != 4 && redisJson.State-last_state > 1 {
m_redis_db.Del(m_md5_tun_key)
utils.Log().DebugF("状态异常: %d -> %d", last_state, redisJson.State)
return nil, nil
return nil, nil, nil, nil
}
redisJson.SocketTimeOut = time_out
@@ -78,13 +82,13 @@ func GetRemoteQuicConn(time_out time.Duration) (quic.Connection, quic.Stream) {
conn_type = 0
utils.Log().Debug("对端未发来IP")
if m_tun_active != nil {
m_tun_active.Release()
if tun_active != nil {
tun_active.Release()
}
m_tun_passive = nil
tun_passive = nil
m_tun_active = tun.CreateTunActive([]byte(redisJson.SessionID), conn, time_out)
tun_active_chain = m_tun_active.GetChain()
tun_active = tun.CreateTunActive([]byte(redisJson.SessionID), conn, time_out)
tun_active_chain = tun_active.GetChain()
redisJson.State = 1
redisJson.SendPortCount = 0x100
@@ -95,28 +99,26 @@ func GetRemoteQuicConn(time_out time.Duration) (quic.Connection, quic.Stream) {
utils.Log().Debug("对端有发来IP")
conn_type = 1
if m_tun_passive != nil {
m_tun_passive.Release()
if tun_passive != nil {
tun_passive.Release()
}
m_tun_active = nil
tun_active = nil
m_tun_passive = tun.CteateTunPassive([]byte(redisJson.SessionID), conn, redisJson.LocalIP, redisJson.LocalPort1, redisJson.LocalPort2, 0x100)
m_tun_passive.Start()
tun_passive = tun.CteateTunPassive([]byte(redisJson.SessionID), conn, redisJson.LocalIP, redisJson.LocalPort1, redisJson.LocalPort2, 0x100)
tun_passive.Start()
tun_passive_chain = m_tun_passive.GetChain()
tun_passive_chain = tun_passive.GetChain()
redisJson.State = 1
utils.Log().DebugF("发送本端地址: %v", redisJson)
RedisSet(redisJson.RedisTimeOut, &redisJson)
go m_tun_passive.Start()
}
case 2:
switch conn_type {
case 0:
utils.Log().DebugF("收到对端地址: %v", redisJson)
m_tun_active.Start(redisJson.RemotePort1, redisJson.RemotePort2, redisJson.LocalIP, redisJson.LocalPort1, redisJson.LocalPort2, redisJson.SocketTimeOut)
tun_active.Start(redisJson.RemotePort1, redisJson.RemotePort2, redisJson.LocalIP, redisJson.LocalPort1, redisJson.LocalPort2, redisJson.SocketTimeOut)
case 1:
utils.Log().DebugF("收到对端地址, 等待连接: %v", redisJson)
@@ -125,27 +127,27 @@ func GetRemoteQuicConn(time_out time.Duration) (quic.Connection, quic.Stream) {
select {
case <-tun_active_chain:
redisJson.State = 3
utils.Log().Debug("通知对端, 连接成功")
utils.Log().Debug("对端被动连接成功")
RedisSet(redisJson.RedisTimeOut, &redisJson)
if m_tun_active != nil {
return m_tun_active.TunQuicConn, m_tun_active.TunHealthStream
if tun_active != nil {
return tun_active, nil, tun_active.TunQuicConn, tun_active.TunHealthStream
}
return nil, nil
return nil, nil, nil, nil
case <-tun_passive_chain:
redisJson.State = 3
utils.Log().Debug("通知对端, 连接成功")
utils.Log().Debug("对端主动连接成功")
RedisSet(redisJson.RedisTimeOut, &redisJson)
if m_tun_passive != nil {
return m_tun_passive.TunQuicConn, m_tun_passive.TunHealthStream
if tun_passive != nil {
return nil, tun_passive, tun_passive.TunQuicConn, tun_passive.TunHealthStream
}
return nil, nil
return nil, nil, nil, nil
case <-time.After(time_out):
redisJson.State = 4
utils.Log().Debug("通知对端, 连接超时")
utils.Log().Debug("对端连接超时")
RedisSet(redisJson.RedisTimeOut, &redisJson)
return nil, nil
return nil, nil, nil, nil
}
case 3, 4:
@@ -157,19 +159,45 @@ func GetRemoteQuicConn(time_out time.Duration) (quic.Connection, quic.Stream) {
last_state = redisJson.State
}
return nil, nil
return nil, nil, nil, nil
}
var (
lock_remote sync.Mutex
tun_active_list []*tun.TunActive
tun_passive_list []*tun.TunPassive
)
func StopRemote() error {
m_remote_stats = 0
Release()
proxy.StopSocks5()
lock_remote.Lock()
defer lock_remote.Unlock()
if tun_active_list != nil {
for _, tun_active := range tun_active_list {
tun_active.Release()
}
tun_active_list = nil
}
if tun_passive_list != nil {
for _, tun_passive := range tun_passive_list {
tun_passive.Release()
}
tun_passive_list = nil
}
return nil
}
func RunRemote(remote_addr string, tun_key string, time_out time.Duration) error {
var wg sync.WaitGroup
tun_active_list = make([]*tun.TunActive, 0)
tun_passive_list = make([]*tun.TunPassive, 0)
if remote_addr == "" {
utils.Log().Debug("开启本地代理")
remote_addr = utils.GetFreeLocalAddr()
@@ -192,16 +220,25 @@ func RunRemote(remote_addr string, tun_key string, time_out time.Duration) error
m_md5_tun_key = md5.Encode(tun_key)
for m_remote_stats == 1 {
conn, health := GetRemoteQuicConn(time_out)
tun_active, tun_passive, conn, health := GetRemoteQuicConn(time_out)
if conn == nil {
Release()
Release(tun_active, tun_passive)
continue
}
lock_remote.Lock()
if tun_active != nil {
tun_active_list = append(tun_active_list, tun_active)
}
if tun_passive != nil {
tun_passive_list = append(tun_passive_list, tun_passive)
}
lock_remote.Unlock()
wg.Add(1)
go func(remote string, conn quic.Connection) {
go func(tun_active2 *tun.TunActive, tun_passive2 *tun.TunPassive, remote string, conn quic.Connection) {
defer func() {
Release()
Release(tun_active2, tun_passive2)
wg.Done()
}()
@@ -213,7 +250,7 @@ func RunRemote(remote_addr string, tun_key string, time_out time.Duration) error
tun.ProcessHealth(health)
utils.Log().DebugF("释放连接: %v", conn.LocalAddr())
}(remote_addr, conn)
}(tun_active, tun_passive, remote_addr, conn)
}
wg.Wait()

View File

@@ -14,8 +14,8 @@ func GetListenUDP() *net.UDPConn {
}
func GetListenUDP2(port int) *net.UDPConn {
if addr, err := net.ResolveUDPAddr("udp", fmt.Sprintf(":%d", port)); addr != nil && err == nil {
if conn, err := net.ListenUDP("udp", addr); conn != nil && err == nil {
if addr, err := net.ResolveUDPAddr("udp4", fmt.Sprintf(":%d", port)); addr != nil && err == nil {
if conn, err := net.ListenUDP("udp4", addr); conn != nil && err == nil {
return conn
}
}