Fix HTTPs with DNS multiaddresses

Before we resolved all /dns*/ multiaddresses before we used them.

When using HTTPs, the Go HTTP Client only sees the resolved IP address
and it is unable to negotiate TLS with a cerficate because the request
is not going to the hostname the certificate is signed for, but to
the IP. This leverages a recent feature in go-multiaddr-net
and uses directly the user-provided hostname.

License: MIT
Signed-off-by: Hector Sanjuan <code@hector.link>
This commit is contained in:
Hector Sanjuan 2018-12-19 21:15:37 +01:00
parent 319c41cbf1
commit 7c26f1ecb8
2 changed files with 21 additions and 10 deletions

View File

@ -221,6 +221,10 @@ func NewDefaultClient(cfg *Config) (Client, error) {
}
func (c *defaultClient) setupAPIAddr() error {
if c.config.APIAddr != nil {
return nil // already setup by user
}
var addr ma.Multiaddr
var err error
if c.config.APIAddr == nil {
@ -238,6 +242,12 @@ func (c *defaultClient) setupAPIAddr() error {
}
func (c *defaultClient) resolveAPIAddr() error {
// Only resolve libp2p addresses. For HTTP addresses, we let
// the default client handle any resolving. We extract the hostname
// in setupHostname()
if !IsPeerAddress(c.config.APIAddr) {
return nil
}
resolveCtx, cancel := context.WithTimeout(c.ctx, ResolveTimeout)
defer cancel()
resolved, err := madns.Resolve(resolveCtx, c.config.APIAddr)
@ -279,13 +289,14 @@ func (c *defaultClient) setupHTTPClient() error {
func (c *defaultClient) setupHostname() error {
// Extract host:port form APIAddr or use Host:Port.
// For libp2p, hostname is set in enableLibp2p()
if !IsPeerAddress(c.config.APIAddr) {
_, hostname, err := manet.DialArgs(c.config.APIAddr)
if err != nil {
return err
}
c.hostname = hostname
if IsPeerAddress(c.config.APIAddr) {
return nil
}
_, hostname, err := manet.DialArgs(c.config.APIAddr)
if err != nil {
return err
}
c.hostname = hostname
return nil
}

View File

@ -185,12 +185,12 @@ func TestDNSMultiaddress(t *testing.T) {
t.Fatal(err)
}
dc := c.(*defaultClient)
if dc.hostname != "127.0.0.1:1234" {
t.Error("bad resolved address")
if dc.hostname != "localhost:1234" {
t.Error("address should not be resolved")
}
if dc.config.ProxyAddr == nil || dc.config.ProxyAddr.String() != "/ip4/127.0.0.1/tcp/9095" {
t.Error("proxy address was not guessed correctly")
if paddr := dc.config.ProxyAddr; paddr == nil || paddr.String() != "/dns4/localhost/tcp/9095" {
t.Error("proxy address was not guessed correctly: ", paddr)
}
}