nodertc/stun

Cannot destructure property 'address' of 'res.getXorAddress(...)' as it is undefined

JabinGP opened this issue · 3 comments

Description: Address in some responses is undefined.
OS: 10.15.6 (19G73)
Node.js: v14.4.0
Stun: 2.1.0

const stun = require('stun');

const freeStunServers = [
    // google
    "stun1.l.google.com:19302",
    "stun2.l.google.com:19302",
    "stun3.l.google.com:19302",
    "stun4.l.google.com:19302",

    // others
    "stun.ekiga.net:3478",
    "stun.schlund.de:3478",
    "stun.xten.com:3478",
]
freeStunServers.forEach( stunURL => {
    stun.request(stunURL, (err, res) => {
        if (err) {
          console.error(err);
        } else {
          let add = res.getXorAddress();
          if (add) {
            const { address, port } = res.getXorAddress();
            console.log(`Res from ${stunURL} : Your IP is ${address} PORT is ${port}.`);
          }else{
            console.log(`Res from ${stunURL} : address is undefined.`);
          }
        }
      });
})

Output:

Res from stun1.l.google.com:19302 : Your IP is 120.236.163.98 PORT is 12422.
Res from stun2.l.google.com:19302 : Your IP is 120.236.163.98 PORT is 8165.
Res from stun.ekiga.net:3478 : address is undefined.
Res from stun.xten.com:3478 : address is undefined.
Res from stun4.l.google.com:19302 : Your IP is 202.116.36.83 PORT is 12715.
Res from stun3.l.google.com:19302 : Your IP is 120.236.163.98 PORT is 8166.
Res from stun.schlund.de:3478 : Your IP is 120.236.163.98 PORT is 5170.

While request the same servers using go and github.com/pion/stun.

package main

import (
	"fmt"
	"log"
	"sync"

	"github.com/pion/stun"
)

var wg sync.WaitGroup

func request(url string) {
	defer func() {
		wg.Done()
	}()
	// Creating a "connection" to STUN server.
	c, err := stun.Dial("udp", url)
	if err != nil {
		log.Println(err)
		return
	}
	// 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(res.Error)
			return
		}
		// Decoding XOR-MAPPED-ADDRESS attribute from message.
		var xorAddr stun.XORMappedAddress
		if err := xorAddr.GetFrom(res.Message); err != nil {
			log.Println(err)
			return
		}
		fmt.Printf("Res from %s : Your IP is %d PORT is %d.\n", url, xorAddr.IP, xorAddr.Port)
	}); err != nil {
		log.Println(err)
		return
	}
}

func main() {
	freeStunServers := []string{
		// google
		"stun1.l.google.com:19302",
		"stun2.l.google.com:19302",
		"stun3.l.google.com:19302",
		"stun4.l.google.com:19302",

		// others
		"stun.ekiga.net:3478",
		"stun.schlund.de:3478",
		"stun.xten.com:3478",
	}
	for _, stun := range freeStunServers {
		wg.Add(1)
		go request(stun)
	}

	wg.Wait()
}

Output:

Res from stun2.l.google.com:19302: Your IP is [120 236 163 98], PORT is 11732.
Res from stun.xten.com:3478: Your IP is [120 236 163 98], PORT is 11735.
Res from stun.ekiga.net:3478: Your IP is [120 236 163 98], PORT is 11734.
Res from stun4.l.google.com:19302: Your IP is [202 116 36 83], PORT is 12765.
Res from stun1.l.google.com:19302: Your IP is [120 236 163 98], PORT is 7958.
Res from stun.schlund.de:3478: Your IP is [120 236 163 98], PORT is 7959.
Res from stun3.l.google.com:19302: Your IP is [120 236 163 98], PORT is 11733.

I got this response from stun.ekiga.net:3478:

StunResponse {
  [Symbol(kMessageType)]: 257,
  [Symbol(kTransctionId)]: <Buffer 02 39 8e bd b1 ae 4c 9d cd ca 87 1a>,
  [Symbol(kCookie)]: 554869826,
  [Symbol(kAttributes)]: [
    StunAddressAttribute {
      [Symbol(kAttributeType)]: 1,
      [Symbol(kPort)]: 53581,
      [Symbol(kAddress)]: '(my ip)',
      [Symbol(kFamily)]: 'IPv4'
    },
    StunUnknownAttribute {
      [Symbol(kAttributeType)]: 4,
      [Symbol(kValue)]: <Buffer 00 01 0d 96 d8 5d f6 12>
    },
    StunUnknownAttribute {
      [Symbol(kAttributeType)]: 5,
      [Symbol(kValue)]: <Buffer 00 01 0d 97 d8 5d f6 0f>
    },
    StunUnknownAttribute {
      [Symbol(kAttributeType)]: 32800,
      [Symbol(kValue)]: <Buffer 00 01 f0 5f 24 b4 07 f2>
    },
    StunByteStringAttribute {
      [Symbol(kAttributeType)]: 32802,
      [Symbol(kValue)]: <Buffer 56 6f 76 69 64 61 2e 6f 72 67 20 30 2e 39 38 2d 43 50 43 00>
    }
  ]
}

I may throw an exception when you try to read non-existed attribute.

@reklatsmasters Thanks for your reply, I solved my problem by using let { address, port } = res.getXorAddress() || res.getAddress();.