mirror of
https://gitee.com/konyshe/goodlink.git
synced 2025-09-26 20:51:22 +08:00
1. 解决部分导致异常退出的问题
2. 进一步分析NAT类型
This commit is contained in:
@@ -4,5 +4,5 @@ Website = "https://goodlink.kony.vip"
|
||||
Icon = "theme/favicon.png"
|
||||
Name = "goodlink-windows-amd64-ui"
|
||||
ID = "goodlink.kony.vip"
|
||||
Version = "1.14.21"
|
||||
Build = 0
|
||||
Version = "1.14.22"
|
||||
Build = 11
|
||||
|
10
pro/comm.go
10
pro/comm.go
@@ -79,13 +79,21 @@ type RedisJsonType struct {
|
||||
ClientPort2 int `bson:"client_port2" json:"client_port2"`
|
||||
}
|
||||
|
||||
func RedisSet(time_out time.Duration, redisJson *RedisJsonType) {
|
||||
func RedisSet(time_out time.Duration, redisJson *RedisJsonType) error {
|
||||
if m_redis_db == nil {
|
||||
return errors.New("Redis为初始化")
|
||||
}
|
||||
if jsonByte, err := json.Marshal(*redisJson); err == nil {
|
||||
m_redis_db.Set(m_md5_tun_key, aes.Encrypt(jsonByte, m_tun_key), time_out)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func RedisGet(redisJson *RedisJsonType) error {
|
||||
if m_redis_db == nil {
|
||||
return errors.New("Redis为初始化")
|
||||
}
|
||||
|
||||
aes_res, err := m_redis_db.Get(m_md5_tun_key).Bytes()
|
||||
if err != nil || aes_res == nil || len(aes_res) == 0 {
|
||||
return fmt.Errorf(" 获取信令数据失败: %v", err)
|
||||
|
21
pro/local.go
21
pro/local.go
@@ -28,32 +28,15 @@ func GetLocalQuicConn(conn_type int, count int) (quic.Connection, quic.Stream, e
|
||||
ConnectCount: count,
|
||||
}
|
||||
|
||||
wan_ip_chain := make(chan string, 1)
|
||||
wan_port1_chain := make(chan int, 1)
|
||||
wan_port2_chain := make(chan int, 1)
|
||||
defer func() {
|
||||
close(wan_ip_chain)
|
||||
close(wan_port1_chain)
|
||||
close(wan_port2_chain)
|
||||
}()
|
||||
|
||||
conn := tools.GetListenUDP()
|
||||
|
||||
go func() {
|
||||
ClientIP, ClientPort1, ClientPort2 := stun2.GetWanIpPort2(conn)
|
||||
wan_ip_chain <- ClientIP
|
||||
wan_port1_chain <- ClientPort1
|
||||
wan_port2_chain <- ClientPort2
|
||||
log.Printf(" 本地地址: %v: %v,%v", ClientIP, ClientPort1, ClientPort2)
|
||||
}()
|
||||
|
||||
switch conn_type {
|
||||
case 0:
|
||||
gogo.Log().Debug("0: 请求连接对端")
|
||||
RedisSet(15*time.Second, &redisJson)
|
||||
|
||||
default:
|
||||
redisJson.ClientIP, redisJson.ClientPort1, redisJson.ClientPort2 = <-wan_ip_chain, <-wan_port1_chain, <-wan_port2_chain
|
||||
redisJson.ClientIP, redisJson.ClientPort1, redisJson.ClientPort2 = stun2.GetWanIpPort2(conn)
|
||||
redisJson.State = 0
|
||||
gogo.Log().DebugF("%d: 发送本端地址: %v", redisJson.State, redisJson)
|
||||
RedisSet(15*time.Second, &redisJson)
|
||||
@@ -79,7 +62,7 @@ func GetLocalQuicConn(conn_type int, count int) (quic.Connection, quic.Stream, e
|
||||
}
|
||||
m_tun_active = nil
|
||||
|
||||
redisJson.ClientIP, redisJson.ClientPort1, redisJson.ClientPort2 = <-wan_ip_chain, <-wan_port1_chain, <-wan_port2_chain
|
||||
redisJson.ClientIP, redisJson.ClientPort1, redisJson.ClientPort2 = stun2.GetWanIpPort2(conn)
|
||||
if redisJson.ClientIP == redisJson.ServerIP {
|
||||
RedisDel()
|
||||
return nil, nil, fmt.Errorf("已经和对端处在同一个公网下")
|
||||
|
59
stun2/cli.go
59
stun2/cli.go
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"goodlink/config"
|
||||
"goodlink/tools"
|
||||
"log"
|
||||
"math/big"
|
||||
"net"
|
||||
"time"
|
||||
@@ -100,7 +101,7 @@ func getStunResponse(conn *net.UDPConn, addr string, buf *bytes.Buffer) ([]byte,
|
||||
|
||||
response := make([]byte, 1024)
|
||||
|
||||
conn.SetReadDeadline(time.Now().Add(2000 * time.Millisecond))
|
||||
conn.SetReadDeadline(time.Now().Add(1000 * time.Millisecond))
|
||||
n, err := conn.Read(response)
|
||||
defer conn.SetDeadline(time.Time{})
|
||||
|
||||
@@ -164,49 +165,61 @@ func getStunIpPort2(conn *net.UDPConn, addr string) (string, int, int, error) {
|
||||
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
||||
wan_ip1, wan_port1, err := getStunIpPort4(response[20:], n, 0x0001, magicCookie, transactionID)
|
||||
if wan_ip1 == "" || wan_port1 == 0 {
|
||||
if err != nil {
|
||||
wan_ip1, wan_port1, err = getStunIpPort4(response[20:], n, 0x0020, magicCookie, transactionID)
|
||||
}
|
||||
if err != nil {
|
||||
return "", 0, 0, err
|
||||
}
|
||||
|
||||
change_ip, change_port, err := getStunIpPort4(response[20:], n, 0x0005, magicCookie, transactionID)
|
||||
if err != nil {
|
||||
return "", 0, 0, err
|
||||
var change_ip, wan_ip2 string
|
||||
var change_port, wan_port2 int
|
||||
|
||||
change_ip, change_port, err = getStunIpPort4(response[20:], n, 0x0005, magicCookie, transactionID)
|
||||
if err == nil {
|
||||
response, n, err = getStunResponse(conn, fmt.Sprintf("%s:%d", change_ip, change_port), buf)
|
||||
if err == nil {
|
||||
wan_ip2, wan_port2, err = getStunIpPort4(response[20:], n, 0x0001, magicCookie, transactionID)
|
||||
if err != nil {
|
||||
wan_ip2, wan_port2, err = getStunIpPort4(response[20:], n, 0x0020, magicCookie, transactionID)
|
||||
}
|
||||
if err == nil {
|
||||
if wan_ip1 != wan_ip2 {
|
||||
gogo.Log().ErrorF("wan_ip: %s, %s", wan_ip1, wan_ip2)
|
||||
}
|
||||
return wan_ip1, wan_port1, wan_port2, nil
|
||||
}
|
||||
}
|
||||
return wan_ip1, wan_port1, 0, err
|
||||
}
|
||||
|
||||
response, n, err = getStunResponse(conn, fmt.Sprintf("%s:%d", change_ip, change_port), buf)
|
||||
if err != nil {
|
||||
return "", 0, 0, err
|
||||
}
|
||||
wan_ip2, wan_port2, err := getStunIpPort4(response[20:], n, 0x0001, magicCookie, transactionID)
|
||||
if wan_ip2 == "" || wan_port2 == 0 {
|
||||
wan_ip2, wan_port2, err = getStunIpPort4(response[20:], n, 0x0020, magicCookie, transactionID)
|
||||
}
|
||||
if err != nil {
|
||||
return "", 0, 0, err
|
||||
}
|
||||
|
||||
if wan_ip1 != wan_ip2 {
|
||||
gogo.Log().ErrorF("wan_ip1: %s, wan_ip2: %s", wan_ip1, wan_ip2)
|
||||
}
|
||||
|
||||
return wan_ip1, wan_port1, wan_port2, nil
|
||||
return wan_ip1, wan_port1, 0, nil
|
||||
}
|
||||
|
||||
func GetWanIpPort2(conn *net.UDPConn) (string, int, int) {
|
||||
gogo.Log().Debug(" 获取本端地址")
|
||||
defer conn.SetReadDeadline(time.Time{})
|
||||
n2 := 0
|
||||
|
||||
for {
|
||||
n, _ := rand.Int(rand.Reader, big.NewInt(int64(len(config.GetConfig().StunList))))
|
||||
stun_svr := config.GetConfig().StunList[n.Int64()]
|
||||
wan_ip, wan_port1, wan_port2, err := getStunIpPort2(conn, stun_svr)
|
||||
//log.Printf(" stun_svr: %s, wan_ip: %s, wan_port1: %d, wan_port2: %d, err: %v", stun_svr, wan_ip, wan_port1, wan_port2, err)
|
||||
if err == nil {
|
||||
if err != nil {
|
||||
log.Printf(" stun_svr: %s, err: %v", stun_svr, err)
|
||||
/*if strings.Contains(err.Error(), "timeout") || strings.Contains(err.Error(), "closed") {
|
||||
time.Sleep(1 * time.Second)
|
||||
}*/
|
||||
}
|
||||
if wan_ip != "" && wan_port1 > 0 {
|
||||
return wan_ip, wan_port1, wan_port2
|
||||
}
|
||||
n2++
|
||||
if n2 >= len(config.GetConfig().StunList) {
|
||||
time.Sleep(3 * time.Second)
|
||||
n2 = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user