Skip to content

Instantly share code, notes, and snippets.

@atotto
Created July 10, 2025 00:59
Show Gist options
  • Select an option

  • Save atotto/0fff265e6d72bc047810bcdde850a7a2 to your computer and use it in GitHub Desktop.

Select an option

Save atotto/0fff265e6d72bc047810bcdde850a7a2 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"net"
"time"
"github.com/pion/stun/v3"
)
func mappedAddr(server string) (string, error) {
conn, err := net.DialTimeout("udp", server, 3*time.Second)
if err != nil {
return "", err
}
defer conn.Close()
c, err := stun.NewClient(conn)
if err != nil {
return "", err
}
defer c.Close()
var xorAddr stun.XORMappedAddress
if err = c.Do(stun.MustBuild(stun.TransactionID, stun.BindingRequest), func(res stun.Event) {
if res.Error != nil {
err = res.Error
return
}
err = xorAddr.GetFrom(res.Message)
}); err != nil {
return "", err
}
return xorAddr.String(), nil
}
func main() {
a, err := mappedAddr("stun.l.google.com:19302")
if err != nil {
fmt.Printf("Error getting mapped address: %v\n", err)
return
}
b, err := mappedAddr("stun1.l.google.com:19302")
if err != nil {
fmt.Printf("Error getting mapped address: %v\n", err)
return
}
switch {
case a == "" || b == "":
fmt.Println("NAT Type F (UDP blocked)")
case a != b:
fmt.Println("NAT Type D (Symmetric)")
default:
fmt.Println("NAT Type B (Cone-type)")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment