Skip to content
This repository has been archived by the owner on Mar 10, 2020. It is now read-only.

Using a multiaddr with DNS fails connect to IPFS node #712

Closed
charlescrain opened this issue Mar 11, 2018 · 9 comments
Closed

Using a multiaddr with DNS fails connect to IPFS node #712

charlescrain opened this issue Mar 11, 2018 · 9 comments

Comments

@charlescrain
Copy link

Hey!

Below is the code I'm using to connect to the infura ipfs node. From what I've read this is an appropriate use of multiaddr but perhaps I'm wrong and would appreciate understanding how to correctly turn https://ipfs.infura.io into a multiaddr.

var ipfsAPI = require('ipfs-api');
var Multiaddr = require('multiaddr')


var maString = '/dns4/ipfs.infura.io/https'; // Is this equivalent to https://ipfs.infura.io?
var ma = Multiaddr(maString);
if (!Multiaddr.isMultiaddr(ma)) {
  console.log('Not a valid multiaddr');
  return;
}

// or connect with multiaddr
var ipfs = ipfsAPI(maString);

var data = Buffer.from('Multiaddrs are cool.', 'utf-8');
ipfs.files.add(data, {}, console.log);

js-multiaddr seems to support dns4 and https but maybe I've misunderstood.

Thanks for any help guys!

-Charles

@daviddias
Copy link
Contributor

@charlescrain we actually never added DNS support to js-ipfs-api client, but it definitely should work. Looks like this is a good first contribution for anyone to take. Would you like to give it a try?

@charlescrain
Copy link
Author

Yeah I'll give her a shot!

@vasco-santos vasco-santos self-assigned this Apr 11, 2018
@vasco-santos
Copy link
Contributor

vasco-santos commented Apr 11, 2018

Hello @charlescrain @diasdavid ,

I gave a look at this issue and I have a few notes regarding it.

Firstly, the currently supported format for a Multiaddr is {IPv4, IPv6}/{TCP, UDP}, or in other words, {Internet Layer}/{Transport Layer} as shown here. Since DNS is an application layer and it is usually sent over the Internet Protocol, it looks quite strange to me. However, the multiaddr documentation accepts it in this way.

All things considered, we may accept {IPv4, IPv6, DNSv4, DNSv6}/{TCP, UDP} in order to allow a multiaddr with DNS.

@charlescrain Taking into account your use case, I think it would be used as follows (53 is the standard port of DNS, afaik):

var maString = '/dns4/ipfs.infura.io/tcp/53'; 
var ma = Multiaddr(maString);

@diasdavid What do you both think about this approach?

Other solution can be the solution that I proposed in #581 (comment). If we support a specific hostname, in this case, we could use the DNS address directly.

@dryajov
Copy link
Contributor

dryajov commented Apr 11, 2018

hrm... this seems to be a legit issue. When I try this code with one of our bootstrap nodes it also fails.

@vasco-santos
Copy link
Contributor

Are you using a multiformat address with dns @dryajov ?

@victorb
Copy link
Contributor

victorb commented Apr 17, 2018

multiaddr as-is does miss some features to be specified, having proper DNS support is one of them and is why DNS is reserved for now, until then we have dns4 and dns6 to resolve A and AAAA records. In this case, dns4 would be the correct one. That's the first part of the multiaddr, /dns/ipfs.infura.io

The second part would be which port to use, in this case we want to use /tcp/5001 as that's where the API is running.

Third part is which protocol to use. This is the part that is a bit under-specified right now. The current thinking (@lgierth, correct me if I'm wrong) is to use /tls/http if https and /http if just http.

So the full multiaddr that has to be supported by the multiaddr package would be /dns4/ipfs.infura.io/tcp/5001/tls/http and outputted in the right format for js-ipfs-api for use.

Steps for moving forward with multiaddr is outlined over here: multiformats/multiaddr#62

@ghost
Copy link

ghost commented Apr 17, 2018

Yes, what @victorbjelkholm said - and /tls and /http could/should actually take one more thing each, the TLS SNI header and the HTTP Host header.

In http(s) URLs, the hostname serves three purposes: DNS lookup, TLS SNI, and HTTP Host, all at once. This coupling of course limits applications in networking stack constructions they can express. Domain fronting for example, where the (cleartext) SNI header is e.g. google.com while the private HTTP Host header is mysite.com, simply can't be expressed.

In a multiaddr, domain fronting could be expressed like this: /dns4/google.com/tcp/443/tls/sni/google.com/http/mysite.com. The /sni part is simple: it's optional, and if it's omitted, the TLS SNI header will simply not be set. But the /http part is a bit tricky. For the sake of encoding/decoding simplicity, we'd probably want multiaddr protocols to always have the same number of values. It's totally okay to make HTTP requests without a Host header, so we wouldn't want to make it mandatory in multiaddr.

There's also the question of how HTTP paths should be represented. In most cases it seems fine to just say "the remainder of the multiaddr is the path", but then sometimes you want to further encapsulate something, e.g. a websocket at a specific path. It's tricky, and there are some notes on how this might look like, but we need to further lay this out and discuss and experiment. For now I'll just use /http/example.com here and disregard the path and backward-compat issues.

These addresses get pretty verbose, but we can have a resolution step which transforms a short multiaddr to its full form, depending on context. For example, a web browser today transforms example.com to http://example.com, and it could transform the same to /http/example.com, then /dns4/example.com/tcp/443/tls/sni/example.com/http/example.com. In the same spirit, the shorthand /https could be transformed to [...]/tls/sni/example.com/http. This can be the same resolution step which already turns /dns4/example.com into /ip4/4.3.2.1.

@vasco-santos
Copy link
Contributor

I see @victorbjelkholm and @lgierth. Thanks for your complete explanation, I will give it a try now.

@vasco-santos
Copy link
Contributor

For allowing the js-ipfs-api to connect with a node through a DNS multiaddr, I created the following PR: multiformats/js-multiaddr#62

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants