mirror of
https://gitee.com/konyshe/goodlink.git
synced 2025-09-26 20:51:22 +08:00
204 lines
4.5 KiB
Go
204 lines
4.5 KiB
Go
package pro
|
|
|
|
import (
|
|
"errors"
|
|
"goodlink/md5"
|
|
"goodlink/proxy"
|
|
"goodlink/stun2"
|
|
"goodlink/tools"
|
|
"goodlink2/tun"
|
|
_ "goodlink2/tun"
|
|
"log"
|
|
"sync"
|
|
"time"
|
|
|
|
"gogo"
|
|
|
|
"github.com/quic-go/quic-go"
|
|
)
|
|
|
|
var (
|
|
m_remote_stats int
|
|
)
|
|
|
|
func GetRemoteQuicConn(time_out time.Duration) (quic.Connection, quic.Stream) {
|
|
redisJson := RedisJsonType{}
|
|
last_state := redisJson.State
|
|
conn_type := 0 //主动连接
|
|
|
|
var tun_active_chain chan quic.Connection
|
|
var tun_passive_chain chan quic.Connection
|
|
|
|
for m_remote_stats == 1 {
|
|
time.Sleep(1 * time.Second)
|
|
|
|
for RedisGet(&redisJson) != nil && m_remote_stats == 1 {
|
|
time.Sleep(5 * time.Second)
|
|
}
|
|
|
|
if redisJson.State < last_state {
|
|
gogo.Log().Debug(" 对端已重置连接")
|
|
return nil, nil
|
|
}
|
|
|
|
if redisJson.State != 3 && redisJson.State != 4 && redisJson.State-last_state > 1 {
|
|
gogo.Log().Debug(" 状态异常")
|
|
m_redis_db.Del(m_md5_tun_key)
|
|
return nil, nil
|
|
}
|
|
|
|
redisJson.SocketTimeOut = time_out
|
|
redisJson.RedisTimeOut = redisJson.SocketTimeOut * 3
|
|
|
|
switch redisJson.State {
|
|
case 0:
|
|
gogo.Log().DebugF("%d: 收到对端请求: %v", redisJson.State, redisJson)
|
|
|
|
conn := tools.GetListenUDP()
|
|
redisJson.ServerIP, redisJson.ServerPort = stun2.GetWanIpPort2(conn)
|
|
|
|
switch redisJson.ClientPort {
|
|
case 0:
|
|
conn_type = 0
|
|
gogo.Log().Debug(" 对端未发来IP")
|
|
|
|
if m_tun_active != nil {
|
|
m_tun_active.Release()
|
|
}
|
|
m_tun_passive = nil
|
|
|
|
m_tun_active = tun.CreateTunActive(conn, time_out)
|
|
tun_active_chain = m_tun_active.GetChain()
|
|
|
|
redisJson.State = 1
|
|
redisJson.SendPortCount = 0x100
|
|
gogo.Log().DebugF("%d: 发送本端地址: %v", redisJson.State, redisJson)
|
|
RedisSet(redisJson.RedisTimeOut, &redisJson)
|
|
|
|
default:
|
|
gogo.Log().Debug(" 对端有发来IP")
|
|
conn_type = 1
|
|
|
|
if m_tun_passive != nil {
|
|
m_tun_passive.Release()
|
|
}
|
|
m_tun_active = nil
|
|
|
|
m_tun_passive = tun.CteateTunPassive(conn, redisJson.ClientIP, redisJson.ClientPort, 0x100)
|
|
m_tun_passive.Start()
|
|
|
|
tun_passive_chain = m_tun_passive.GetChain()
|
|
|
|
redisJson.State = 1
|
|
gogo.Log().DebugF("%d: 发送本端地址: %v", redisJson.State, redisJson)
|
|
RedisSet(redisJson.RedisTimeOut, &redisJson)
|
|
}
|
|
|
|
case 2:
|
|
switch conn_type {
|
|
case 0:
|
|
gogo.Log().DebugF("%d: 收到对端地址: %v", redisJson.State, redisJson)
|
|
m_tun_active.Start(redisJson.ServerPort, redisJson.ClientIP, redisJson.ClientPort, redisJson.SocketTimeOut)
|
|
|
|
case 1:
|
|
gogo.Log().DebugF("%d: 收到对端地址, 等待连接: %v", redisJson.State, redisJson)
|
|
}
|
|
|
|
select {
|
|
case <-tun_active_chain:
|
|
redisJson.State = 3
|
|
gogo.Log().DebugF("%d: 通知对端, 连接成功", redisJson.State)
|
|
RedisSet(redisJson.RedisTimeOut, &redisJson)
|
|
if m_tun_active != nil {
|
|
return m_tun_active.TunQuicConn, m_tun_active.TunHealthStream
|
|
}
|
|
return nil, nil
|
|
|
|
case <-tun_passive_chain:
|
|
redisJson.State = 3
|
|
gogo.Log().DebugF("%d: 通知对端, 连接成功", redisJson.State)
|
|
RedisSet(redisJson.RedisTimeOut, &redisJson)
|
|
if m_tun_passive != nil {
|
|
return m_tun_passive.TunQuicConn, m_tun_passive.TunHealthStream
|
|
}
|
|
return nil, nil
|
|
|
|
case <-time.After(time_out):
|
|
redisJson.State = 4
|
|
gogo.Log().DebugF("%d: 通知对端, 连接超时", redisJson.State)
|
|
RedisSet(redisJson.RedisTimeOut, &redisJson)
|
|
return nil, nil
|
|
}
|
|
|
|
case 3, 4:
|
|
|
|
default:
|
|
gogo.Log().DebugF("%d: 等待对端状态", redisJson.State)
|
|
}
|
|
|
|
last_state = redisJson.State
|
|
}
|
|
|
|
return nil, nil
|
|
}
|
|
|
|
func StopRemote() error {
|
|
m_remote_stats = 0
|
|
Release()
|
|
proxy.StopSocks5()
|
|
return nil
|
|
}
|
|
|
|
func RunRemote(remote_addr string, tun_key string, time_out time.Duration) error {
|
|
var wg sync.WaitGroup
|
|
|
|
if remote_addr == "" {
|
|
log.Println(" 开启本地代理")
|
|
remote_addr = tools.GetFreeLocalAddr()
|
|
if remote_addr == "" {
|
|
return errors.New(" 获取本地端口失败")
|
|
}
|
|
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
proxy.ListenSocks5(remote_addr)
|
|
}()
|
|
}
|
|
|
|
log.Printf(" 转发地址: %s", remote_addr)
|
|
|
|
m_remote_stats = 1
|
|
|
|
m_tun_key = tun_key
|
|
m_md5_tun_key = md5.Encode(tun_key)
|
|
|
|
for m_remote_stats == 1 {
|
|
conn, health := GetRemoteQuicConn(time_out)
|
|
if conn == nil {
|
|
Release()
|
|
continue
|
|
}
|
|
|
|
wg.Add(1)
|
|
go func(remote string, conn quic.Connection) {
|
|
defer func() {
|
|
Release()
|
|
wg.Done()
|
|
}()
|
|
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
proxy.ProcessProxyServer(remote, conn)
|
|
}()
|
|
|
|
tun.ProcessHealth(health)
|
|
gogo.Log().DebugF(" 释放连接: %v", conn.LocalAddr())
|
|
}(remote_addr, conn)
|
|
}
|
|
|
|
wg.Wait()
|
|
return nil
|
|
}
|