mirror of
https://github.com/oneclickvirt/gostun.git
synced 2025-10-06 07:37:03 +08:00
fix: 适配支持RFC 3489/5389/5780检测
This commit is contained in:
143
cmd/main.go
143
cmd/main.go
@@ -12,6 +12,67 @@ import (
|
||||
"github.com/pion/logging"
|
||||
)
|
||||
|
||||
// tryRFCMethod attempts NAT detection using specified RFC method
|
||||
func tryRFCMethod(addrStr string, rfcMethod string) (bool, error) {
|
||||
currentProtocol := "ipv4"
|
||||
if model.IPVersion == "ipv6" || (model.IPVersion == "both" && strings.Contains(addrStr, "[") && strings.Contains(addrStr, "]")) {
|
||||
currentProtocol = "ipv6"
|
||||
}
|
||||
var err1, err2 error
|
||||
switch rfcMethod {
|
||||
case "RFC5780":
|
||||
if model.EnableLoger {
|
||||
model.Log.Infof("[%s] Trying RFC 5780 method with server %s", currentProtocol, addrStr)
|
||||
}
|
||||
err1 = stuncheck.MappingTests(addrStr)
|
||||
if err1 != nil {
|
||||
model.NatMappingBehavior = "inconclusive"
|
||||
if model.EnableLoger {
|
||||
model.Log.Warnf("[%s] RFC5780 NAT mapping behavior: inconclusive", currentProtocol)
|
||||
}
|
||||
}
|
||||
err2 = stuncheck.FilteringTests(addrStr)
|
||||
if err2 != nil {
|
||||
model.NatFilteringBehavior = "inconclusive"
|
||||
if model.EnableLoger {
|
||||
model.Log.Warnf("[%s] RFC5780 NAT filtering behavior: inconclusive", currentProtocol)
|
||||
}
|
||||
}
|
||||
case "RFC5389":
|
||||
if model.EnableLoger {
|
||||
model.Log.Infof("[%s] Trying RFC 5389/8489 method with server %s", currentProtocol, addrStr)
|
||||
}
|
||||
err1 = stuncheck.MappingTestsRFC5389(addrStr)
|
||||
if err1 != nil {
|
||||
model.NatMappingBehavior = "inconclusive"
|
||||
model.NatFilteringBehavior = "inconclusive"
|
||||
if model.EnableLoger {
|
||||
model.Log.Warnf("[%s] RFC5389 NAT detection: inconclusive", currentProtocol)
|
||||
}
|
||||
}
|
||||
case "RFC3489":
|
||||
if model.EnableLoger {
|
||||
model.Log.Infof("[%s] Trying RFC 3489 method with server %s", currentProtocol, addrStr)
|
||||
}
|
||||
err1 = stuncheck.MappingTestsRFC3489(addrStr)
|
||||
if err1 != nil {
|
||||
model.NatMappingBehavior = "inconclusive"
|
||||
model.NatFilteringBehavior = "inconclusive"
|
||||
if model.EnableLoger {
|
||||
model.Log.Warnf("[%s] RFC3489 NAT detection: inconclusive", currentProtocol)
|
||||
}
|
||||
}
|
||||
}
|
||||
if model.NatMappingBehavior != "inconclusive" && model.NatFilteringBehavior != "inconclusive" &&
|
||||
model.NatMappingBehavior != "" && model.NatFilteringBehavior != "" {
|
||||
if model.EnableLoger {
|
||||
model.Log.Infof("[%s] Successfully determined NAT type using %s with server %s", currentProtocol, rfcMethod, addrStr)
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
var showVersion, help bool
|
||||
gostunFlag := flag.NewFlagSet("gostun", flag.ContinueOnError)
|
||||
@@ -57,53 +118,49 @@ func main() {
|
||||
} else {
|
||||
addrStrList = model.GetDefaultServers(model.IPVersion)
|
||||
}
|
||||
// checkStatus := false
|
||||
for _, addrStr := range addrStrList {
|
||||
model.NatMappingBehavior = ""
|
||||
model.NatFilteringBehavior = ""
|
||||
currentProtocol := "ipv4"
|
||||
if originalIPVersion == "both" {
|
||||
if strings.Contains(addrStr, "[") && strings.Contains(addrStr, "]") &&
|
||||
!strings.Contains(addrStr, ".") {
|
||||
currentProtocol = "ipv6"
|
||||
model.IPVersion = "ipv6"
|
||||
} else {
|
||||
currentProtocol = "ipv4"
|
||||
model.IPVersion = "ipv4"
|
||||
}
|
||||
} else {
|
||||
currentProtocol = originalIPVersion
|
||||
}
|
||||
if model.EnableLoger {
|
||||
model.Log.Infof("Testing server %s with protocol %s", addrStr, currentProtocol)
|
||||
}
|
||||
err1 := stuncheck.MappingTests(addrStr)
|
||||
if err1 != nil {
|
||||
model.NatMappingBehavior = "inconclusive"
|
||||
if model.EnableLoger {
|
||||
model.Log.Warnf("[%s] NAT mapping behavior: inconclusive", currentProtocol)
|
||||
}
|
||||
}
|
||||
err2 := stuncheck.FilteringTests(addrStr)
|
||||
if err2 != nil {
|
||||
model.NatFilteringBehavior = "inconclusive"
|
||||
if model.EnableLoger {
|
||||
model.Log.Warnf("[%s] NAT filtering behavior: inconclusive", currentProtocol)
|
||||
}
|
||||
}
|
||||
if model.NatMappingBehavior != "inconclusive" && model.NatFilteringBehavior != "inconclusive" &&
|
||||
model.NatMappingBehavior != "" && model.NatFilteringBehavior != "" {
|
||||
// checkStatus = true
|
||||
if model.EnableLoger {
|
||||
model.Log.Infof("[%s] Successfully determined NAT type with server %s", currentProtocol, addrStr)
|
||||
}
|
||||
// RFC methods in order of preference: 5780 -> 5389 -> 3489
|
||||
rfcMethods := []string{"RFC5780", "RFC5389", "RFC3489"}
|
||||
successfulDetection := false
|
||||
for _, rfcMethod := range rfcMethods {
|
||||
if successfulDetection {
|
||||
break
|
||||
}
|
||||
if model.EnableLoger {
|
||||
model.Log.Warnf("[%s] Server %s failed to determine NAT type, trying next server", currentProtocol, addrStr)
|
||||
for _, addrStr := range addrStrList {
|
||||
model.NatMappingBehavior = ""
|
||||
model.NatFilteringBehavior = ""
|
||||
currentProtocol := "ipv4"
|
||||
if originalIPVersion == "both" {
|
||||
if strings.Contains(addrStr, "[") && strings.Contains(addrStr, "]") &&
|
||||
!strings.Contains(addrStr, ".") {
|
||||
currentProtocol = "ipv6"
|
||||
model.IPVersion = "ipv6"
|
||||
} else {
|
||||
currentProtocol = "ipv4"
|
||||
model.IPVersion = "ipv4"
|
||||
}
|
||||
} else {
|
||||
currentProtocol = originalIPVersion
|
||||
}
|
||||
if model.EnableLoger {
|
||||
model.Log.Infof("Testing server %s with protocol %s using %s", addrStr, currentProtocol, rfcMethod)
|
||||
}
|
||||
success, err := tryRFCMethod(addrStr, rfcMethod)
|
||||
if err != nil && model.EnableLoger {
|
||||
model.Log.Warnf("[%s] Error with %s method: %v", currentProtocol, rfcMethod, err)
|
||||
}
|
||||
if success {
|
||||
successfulDetection = true
|
||||
break
|
||||
}
|
||||
if model.EnableLoger {
|
||||
model.Log.Warnf("[%s] Server %s failed to determine NAT type using %s, trying next server", currentProtocol, addrStr, rfcMethod)
|
||||
}
|
||||
}
|
||||
if !successfulDetection && model.EnableLoger {
|
||||
model.Log.Warnf("All servers failed with %s method, trying next RFC method", rfcMethod)
|
||||
}
|
||||
}
|
||||
model.IPVersion = originalIPVersion
|
||||
res := stuncheck.CheckType()
|
||||
fmt.Printf("NAT Type: %s\n", res)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user