Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix stun server switch issue #954

Merged
merged 5 commits into from
Dec 20, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 21 additions & 12 deletions stun/stun.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"net"
"strconv"
"strings"
"time"

"github.com/gravitl/netclient/config"
"github.com/gravitl/netmaker/logger"
Expand Down Expand Up @@ -94,20 +95,22 @@ func HolePunch(portToStun, proto int) (publicIP net.IP, publicPort int, natType
}

for _, stunServer := range StunServers {
stunServer := stunServer
var err error
var err4 error
var err6 error
if proto == 4 {
publicIP, publicPort, natType, err = callHolePunch(stunServer, portToStun, "udp4")
if err != nil {
slog.Warn("callHolePunch udp4 error", err.Error())
publicIP, publicPort, natType, err4 = callHolePunch(stunServer, portToStun, "udp4")
if err4 != nil {
slog.Warn("callHolePunch udp4 error", err4.Error())
}
} else {
publicIP, publicPort, natType, err = callHolePunch(stunServer, portToStun, "udp6")
if err != nil {
slog.Warn("callHolePunch udp6 error", err.Error())
continue
publicIP, publicPort, natType, err6 = callHolePunch(stunServer, portToStun, "udp6")
if err6 != nil {
slog.Warn("callHolePunch udp6 error", err6.Error())
}
}
if err4 != nil || err6 != nil {
continue
}
break
}
slog.Debug("hole punching complete", "public ip", publicIP.String(), "public port", strconv.Itoa(publicPort), "nat type", natType)
Expand All @@ -128,7 +131,7 @@ func callHolePunch(stunServer StunServer, portToStun int, network string) (publi
publicIP, publicPort, natType, err = doStunTransaction(l, s)
if err != nil {
logger.Log(3, "stun transaction failed: ", stunServer.Domain, err.Error())
return nil, 0, "", err
return nil, 0, natType, err
}

return
Expand All @@ -152,14 +155,14 @@ func doStunTransaction(lAddr, rAddr *net.UDPAddr) (publicIP net.IP, publicPort i

privIp := net.ParseIP(lIP)
defer func() {
if !privIp.Equal(publicIP) {
if publicIP != nil && privIp != nil && !privIp.Equal(publicIP) {
natType = nmmodels.NAT_Types.BehindNAT
} else {
natType = nmmodels.NAT_Types.Public
}
}()
defer conn.Close()
c, err := stun.NewClient(conn)
c, err := stun.NewClient(conn, stun.WithTimeoutRate(time.Second*5))
if err != nil {
logger.Log(1, "failed to create stun client: ", err.Error())
return
Expand All @@ -168,9 +171,11 @@ func doStunTransaction(lAddr, rAddr *net.UDPAddr) (publicIP net.IP, publicPort i
// Building binding request with random transaction id.
message := stun.MustBuild(stun.TransactionID, stun.BindingRequest)
// Sending request to STUN server, waiting for response message.
var err1 error
err = c.Do(message, func(res stun.Event) {
if res.Error != nil {
logger.Log(1, "0:stun error: ", res.Error.Error())
err1 = res.Error
return
}
// Decoding XOR-MAPPED-ADDRESS attribute from message.
Expand All @@ -185,5 +190,9 @@ func doStunTransaction(lAddr, rAddr *net.UDPAddr) (publicIP net.IP, publicPort i
if err != nil {
logger.Log(1, "2:stun error: ", err.Error())
}
if err1 != nil {
logger.Log(3, "3:stun error: ", err1.Error())
return nil, 0, natType, err1
}
return
}
Loading