netmaker/nm-proxy/stun/stun.go
2022-10-28 17:08:50 +05:30

70 lines
1.5 KiB
Go

package stun
import (
"fmt"
"log"
"net"
"strconv"
"strings"
"gortc.io/stun"
)
type HostInfo struct {
PublicIp net.IP
PrivIp net.IP
PubPort int
PrivPort int
}
var Host HostInfo
func GetHostInfo() (info HostInfo) {
s, err := net.ResolveUDPAddr("udp", "stun.nm.134.209.115.146.nip.io:3478")
if err != nil {
log.Fatal("Resolve: ", err)
}
l := &net.UDPAddr{
IP: net.ParseIP(""),
Port: 51722,
}
conn, err := net.DialUDP("udp", l, s)
if err != nil {
log.Fatal(err)
}
defer conn.Close()
fmt.Printf("%+v\n", conn.LocalAddr())
c, err := stun.NewClient(conn)
if err != nil {
panic(err)
}
defer c.Close()
re := strings.Split(conn.LocalAddr().String(), ":")
info.PrivIp = net.ParseIP(re[0])
info.PrivPort, _ = strconv.Atoi(re[1])
// Building binding request with random transaction id.
message := stun.MustBuild(stun.TransactionID, stun.BindingRequest)
//fmt.Printf("MESG: %+v\n", message)
// Sending request to STUN server, waiting for response message.
if err := c.Do(message, func(res stun.Event) {
//fmt.Printf("RESP: %+v\n", res)
if res.Error != nil {
panic(res.Error)
}
// Decoding XOR-MAPPED-ADDRESS attribute from message.
var xorAddr stun.XORMappedAddress
if err := xorAddr.GetFrom(res.Message); err != nil {
panic(err)
}
info.PublicIp = xorAddr.IP
info.PubPort = xorAddr.Port
}); err != nil {
panic(err)
}
return
}
// /tmp/netclient daemon > /tmp/netclient.out 2>&1
// tcpdump -evvvttttni any 'udp port 51820'