mirror of
https://gitee.com/konyshe/goodlink.git
synced 2025-12-24 08:13:00 +08:00
274 lines
6.7 KiB
Go
274 lines
6.7 KiB
Go
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
|
||
}
|