Files
goodlink/pro/remote.go
kony b21b9d8828 u
2025-09-22 16:19:18 +08:00

274 lines
6.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package pro
import (
"go2"
"goodlink/config"
"goodlink/proxy"
"goodlink/utils"
"goodlink2/tun"
"log"
"net"
"strings"
"sync"
"time"
"github.com/quic-go/quic-go"
)
var (
m_remote_stats int
)
func GetRemoteQuicConn() (*net.UDPConn, *tun.TunActive, *tun.TunPassive, quic.Connection, quic.Stream) {
var tun_active *tun.TunActive
var tun_passive *tun.TunPassive
var udp_conn *net.UDPConn
redisJson := RedisJsonType{}
last_state := redisJson.State
conn_type := 0 //主动连接
var tun_active_chain chan quic.Connection
var tun_passive_chain chan quic.Connection
for {
if m_remote_stats != 1 {
//如果UI上点了停止则退出
return nil, nil, nil, nil, nil
}
if RedisGet(&redisJson) == nil {
// 如果收到Local端的请求
if redisJson.State == 0 {
// 收到的第一个请求状态应该是0否则是异常
break
}
}
time.Sleep(5 * time.Second)
}
redisJson.RemoteVersion = GetVersion()
SessionID := redisJson.SessionID
log.Printf("会话ID: %s", SessionID)
for m_remote_stats == 1 {
time.Sleep(1 * time.Second)
if RedisGet(&redisJson) != nil {
log.Println("会话超时")
return udp_conn, tun_active, tun_passive, nil, nil
}
redisJson.RemoteVersion = GetVersion()
//log.Printf("状态消息: %v", redisJson)
utils.Log().SetDebugSate(redisJson.State)
if !strings.EqualFold(redisJson.SessionID, SessionID) {
utils.Log().Debug("会话被重置")
return udp_conn, tun_active, tun_passive, 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 udp_conn, tun_active, tun_passive, 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 udp_conn, tun_active, tun_passive, nil, nil
}
redisJson.SocketTimeOut = time.Duration(config.Arg_p2p_timeout) * time.Second
redisJson.RedisTimeOut = redisJson.SocketTimeOut * 3
switch redisJson.State {
case 0:
utils.Log().DebugF("收到Local端请求: %v", redisJson)
redisJson.State = 1
if redisJson.LocalVersion != GetVersion() {
utils.Log().DebugF("两端版本不兼容: Local: %v => Remote: %v", redisJson.LocalVersion, GetVersion())
RedisSet(redisJson.SocketTimeOut*3, &redisJson)
return udp_conn, tun_active, tun_passive, nil, nil
}
udp_conn, redisJson.RemoteAddr = GetUDPAddr()
switch redisJson.LocalAddr.WanPort1 {
case 0:
conn_type = 0
utils.Log().Debug("Local端未发来IP")
if tun_active != nil {
tun_active.Release()
}
tun_passive = nil
tun_active = tun.CreateTunActive([]byte(redisJson.SessionID), udp_conn, &redisJson.RemoteAddr, &redisJson.LocalAddr, time.Duration(config.Arg_conn_active_send_time)*time.Millisecond)
tun_active_chain = tun_active.GetChain()
redisJson.SendPortCount = 0x100
default:
utils.Log().DebugF("Local端有发来IP: %v", redisJson.LocalAddr)
conn_type = 1
if tun_passive != nil {
tun_passive.Release()
}
tun_active = nil
tun_passive = tun.CreateTunPassive([]byte(redisJson.SessionID), udp_conn, &redisJson.RemoteAddr, &redisJson.LocalAddr, 0x100, time.Duration(config.Arg_conn_passive_send_time)*time.Millisecond)
tun_passive.Start()
tun_passive_chain = tun_passive.GetChain()
}
utils.Log().DebugF("发送Remote端地址: %v", redisJson.RemoteAddr)
RedisSet(redisJson.RedisTimeOut, &redisJson)
case 2:
switch conn_type {
case 0:
utils.Log().DebugF("收到Local端地址: %v", redisJson.LocalAddr)
tun_active.Start()
case 1:
utils.Log().DebugF("收到Local端地址, 等待连接: %v", redisJson.LocalAddr)
}
select {
case <-tun_active_chain:
redisJson.State = 3
utils.Log().Debug("Local端被动连接成功")
RedisSet(redisJson.RedisTimeOut, &redisJson)
if tun_active != nil {
return udp_conn, tun_active, tun_passive, tun_active.TunQuicConn, tun_active.TunHealthStream
}
return udp_conn, tun_active, tun_passive, nil, nil
case <-tun_passive_chain:
redisJson.State = 3
utils.Log().Debug("Local端主动连接成功")
RedisSet(redisJson.RedisTimeOut, &redisJson)
if tun_passive != nil {
return udp_conn, tun_active, tun_passive, tun_passive.TunQuicConn, tun_passive.TunHealthStream
}
return udp_conn, tun_active, tun_passive, nil, nil
case <-time.After(time.Duration(config.Arg_p2p_timeout) * time.Second):
redisJson.State = 4
utils.Log().Debug("Local端连接超时")
RedisSet(redisJson.RedisTimeOut, &redisJson)
return udp_conn, tun_active, tun_passive, nil, nil
}
case 3, 4:
default:
utils.Log().DebugF("等待Local端状态: Local: %v => Remote: %v", redisJson.LocalAddr, redisJson.RemoteAddr)
}
last_state = redisJson.State
}
return udp_conn, tun_active, tun_passive, nil, nil
}
var (
lock_remote sync.Mutex
tun_active_list []*tun.TunActive
tun_passive_list []*tun.TunPassive
udp_conn_list []*net.UDPConn
)
func StopRemote() error {
m_remote_stats = 0
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
}
if udp_conn_list != nil {
for _, udp_conn := range udp_conn_list {
udp_conn.Close()
}
udp_conn_list = nil
}
return nil
}
func RunRemote(tun_key string) error {
var wg sync.WaitGroup
tun_active_list = make([]*tun.TunActive, 0)
tun_passive_list = make([]*tun.TunPassive, 0)
udp_conn_list = make([]*net.UDPConn, 0)
m_remote_stats = 1
m_tun_key = tun_key
m_md5_tun_key = go2.Md5Encode(tun_key)
for m_remote_stats == 1 {
udp_conn, tun_active, tun_passive, quic_conn, health := GetRemoteQuicConn()
if quic_conn == nil {
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)
}
if udp_conn != nil {
udp_conn_list = append(udp_conn_list, udp_conn)
}
lock_remote.Unlock()
wg.Add(1)
go func(tun_active2 *tun.TunActive, tun_passive2 *tun.TunPassive, quic_conn2 quic.Connection) {
defer func() {
Release(tun_active2, tun_passive2)
wg.Done()
}()
wg.Add(1)
go func() {
defer wg.Done()
proxy.ProcessProxyServer(quic_conn2)
}()
tun.ProcessHealth(health)
utils.Log().DebugF("释放连接: %v", quic_conn2.LocalAddr())
}(tun_active, tun_passive, quic_conn)
}
wg.Wait()
return nil
}