coapjs / node-coap

CoAP - Node.js style
MIT License
531 stars 154 forks source link

Automatic selection of IPv4 vs IPv6 sockets when using DNS names #320

Open rubdos opened 2 years ago

rubdos commented 2 years ago

This supersedes https://github.com/JKRhb/node-red-contrib-coap/issues/15.

Currently, the API of node-coap requires you to select whether you want to create a v4 or a v6 socket; this property is inherited from the dgram.socket APIs. However, when connecting via a DNS name, this should be automatically selected based on the DNS records that are found. If I send something to coap://lamp1a/lamp/dimming, and lamp1a returns an AAAA record, the API of node-coap should be able to auto-select a v6 socket. Manually selecting v4/v6 should only be a thing for listening sockets, not for sending sockets.

That said, the NodeJS dgram.createSocket API doesn't seem to comprehend this. I am not sure how this should be solved in NodeJS, especially since the socket.send API allows to supply a hostname. It seems to me that DNS lookups and connection management should be handled outside of the dgram API.

JKRhb commented 2 years ago

In theory there is already a function call to determine whether or not a hostname represents an IPv6 address:

https://github.com/mcollina/node-coap/blob/47b6a1eb18bdb9e215e8412c624163e72c8061bd/index.ts#L73

However, this function seems to only check if the provided hostname matches a regular expression for IPv6 addresses (c. f. the source code).

I guess we should probably add an additional test for DNS names (using the dns module) if the hostname does not match an IP address.

rubdos commented 2 years ago

I guess we should probably add an additional test for DNS names (using the dns module) if the hostname does not match an IP address.

Given that the UDP socket is not smart enough, I think indeed you'll need manual address lookup, and then connect to any found AAAA address, and then fall back to any found A address. We probably need to read some RFC that covers this kind of fallback procedure though.