123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- package stun
- import (
- "fmt"
- "log"
- "net"
- "strconv"
- "strings"
- "github.com/gravitl/netmaker/nm-proxy/models"
- "gortc.io/stun"
- )
- type HostInfo struct {
- PublicIp net.IP
- PrivIp net.IP
- PubPort int
- PrivPort int
- }
- var Host HostInfo
- func GetHostInfo(stunHostAddr string) (info HostInfo) {
- s, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:3478", stunHostAddr))
- if err != nil {
- log.Println("Resolve: ", err)
- return
- }
- l := &net.UDPAddr{
- IP: net.ParseIP(""),
- Port: models.NmProxyPort,
- }
- conn, err := net.DialUDP("udp", l, s)
- if err != nil {
- log.Println(err)
- return
- }
- defer conn.Close()
- c, err := stun.NewClient(conn)
- if err != nil {
- log.Println(err)
- return
- }
- 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)
- // Sending request to STUN server, waiting for response message.
- if err := c.Do(message, func(res stun.Event) {
- if res.Error != nil {
- log.Println("stun error: ", res.Error)
- return
- }
- // Decoding XOR-MAPPED-ADDRESS attribute from message.
- var xorAddr stun.XORMappedAddress
- if err := xorAddr.GetFrom(res.Message); err != nil {
- log.Println("stun error: ", res.Error)
- return
- }
- info.PublicIp = xorAddr.IP
- info.PubPort = xorAddr.Port
- }); err != nil {
- log.Println("stun error: ", err)
- }
- return
- }
|