Skip to content

Commit

Permalink
daemon: support unix domain sockets for the API/gateway
Browse files Browse the repository at this point in the history
All the work was client-side. Unix domain socket multiaddrs already worked
server-side.

fixes ipfs#4218
  • Loading branch information
Stebalien authored and Walter Beegle committed Jun 8, 2020
1 parent 37f89f1 commit 7911711
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 52 deletions.
30 changes: 24 additions & 6 deletions cmd/ipfs/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"errors"
"fmt"
"math/rand"
"net"
"net/http"
"os"
"runtime/pprof"
"strings"
Expand All @@ -22,7 +24,7 @@ import (

"github.com/ipfs/go-ipfs-cmds"
"github.com/ipfs/go-ipfs-cmds/cli"
"github.com/ipfs/go-ipfs-cmds/http"
cmdhttp "github.com/ipfs/go-ipfs-cmds/http"
"github.com/ipfs/go-ipfs-config"
u "github.com/ipfs/go-ipfs-util"
logging "github.com/ipfs/go-log"
Expand Down Expand Up @@ -249,23 +251,39 @@ func makeExecutor(req *cmds.Request, env interface{}) (cmds.Executor, error) {
if err != nil {
return nil, err
}
_, host, err := manet.DialArgs(apiAddr)
network, host, err := manet.DialArgs(apiAddr)
if err != nil {
return nil, err
}

// Construct the executor.
opts := []http.ClientOpt{
http.ClientWithAPIPrefix(corehttp.APIPath),
opts := []cmdhttp.ClientOpt{
cmdhttp.ClientWithAPIPrefix(corehttp.APIPath),
}

// Fallback on a local executor if we (a) have a repo and (b) aren't
// forcing a daemon.
if !daemonRequested && fsrepo.IsInitialized(cctx.ConfigRoot) {
opts = append(opts, http.ClientWithFallback(exe))
opts = append(opts, cmdhttp.ClientWithFallback(exe))
}

switch network {
case "tcp", "tcp4", "tcp6":
case "unix":
path := host
host = "unix"
opts = append(opts, cmdhttp.ClientWithHTTPClient(&http.Client{
Transport: &http.Transport{
DialContext: func(_ context.Context, _, _ string) (net.Conn, error) {
return net.Dial("unix", path)
},
},
}))
default:
return nil, fmt.Errorf("unsupported API address: %s", apiAddr)
}

return http.NewClient(host, opts...), nil
return cmdhttp.NewClient(host, opts...), nil
}

// commandDetails returns a command's details for the command given by |path|.
Expand Down
16 changes: 16 additions & 0 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,32 @@ Contains information about various listener addresses to be used by this node.
- `API`
Multiaddr or array of multiaddrs describing the address to serve the local HTTP API on.

Supported Transports:

* tcp/ip{4,6} - `/ipN/.../tcp/...`
* unix - `/unix/path/to/socket`

Default: `/ip4/127.0.0.1/tcp/5001`

- `Gateway`
Multiaddr or array of multiaddrs describing the address to serve the local gateway on.

Supported Transports:

* tcp/ip{4,6} - `/ipN/.../tcp/...`
* unix - `/unix/path/to/socket`

Default: `/ip4/127.0.0.1/tcp/8080`

- `Swarm`
Array of multiaddrs describing which addresses to listen on for p2p swarm connections.

Supported Transports:

* tcp/ip{4,6} - `/ipN/.../tcp/...`
* websocket - `/ipN/.../tcp/.../ws`
* quic - `/ipN/.../udp/.../quic`

Default:
```json
[
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@ github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IW
github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk=
github.com/ipfs/go-ipfs-chunker v0.0.1 h1:cHUUxKFQ99pozdahi+uSC/3Y6HeRpi9oTeUHbE27SEw=
github.com/ipfs/go-ipfs-chunker v0.0.1/go.mod h1:tWewYK0we3+rMbOh7pPFGDyypCtvGcBFymgY4rSDLAw=
github.com/ipfs/go-ipfs-cmds v0.1.0 h1:0CEde9EcxByej8+L6d1PST57J4ambRPyCTjLG5Ymou8=
github.com/ipfs/go-ipfs-cmds v0.1.0/go.mod h1:TiK4e7/V31tuEb8YWDF8lN3qrnDH+BS7ZqWIeYJlAs8=
github.com/ipfs/go-ipfs-cmds v0.1.1 h1:H9/BLf5rcsULHMj/x8gC0e5o+raYhqk1OQsfzbGMNM4=
github.com/ipfs/go-ipfs-cmds v0.1.1/go.mod h1:k1zMXcOLtljA9iAnZHddbH69yVm5+weRL0snmMD/rK0=
github.com/ipfs/go-ipfs-config v0.0.11 h1:5/4nas2CQXiKr2/MLxU24GDGTBvtstQIQezuk7ltOQQ=
github.com/ipfs/go-ipfs-config v0.0.11/go.mod h1:wveA8UT5ywN26oKStByzmz1CO6cXwLKKM6Jn/Hfw08I=
github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw=
Expand Down Expand Up @@ -596,8 +596,8 @@ github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.3 h1:CTwfnzjQ+8dS6MhHHu4YswVAD99sL2wjPqP+VkURmKE=
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI=
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
Expand Down
50 changes: 8 additions & 42 deletions test/dependencies/pollEndpoint/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ package main

import (
"flag"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"os"
"time"

Expand All @@ -16,11 +12,10 @@ import (
)

var (
host = flag.String("host", "/ip4/127.0.0.1/tcp/5001", "the multiaddr host to dial on")
endpoint = flag.String("ep", "/version", "which http endpoint path to hit")
tries = flag.Int("tries", 10, "how many tries to make before failing")
timeout = flag.Duration("tout", time.Second, "how long to wait between attempts")
verbose = flag.Bool("v", false, "verbose logging")
host = flag.String("host", "/ip4/127.0.0.1/tcp/5001", "the multiaddr host to dial on")
tries = flag.Int("tries", 10, "how many tries to make before failing")
timeout = flag.Duration("tout", time.Second, "how long to wait between attempts")
verbose = flag.Bool("v", false, "verbose logging")
)

var log = logging.Logger("pollEndpoint")
Expand All @@ -33,56 +28,27 @@ func main() {
if err != nil {
log.Fatal("NewMultiaddr() failed: ", err)
}
p := addr.Protocols()
if len(p) < 2 {
log.Fatal("need two protocols in host flag (/ip/tcp): ", addr)
}
_, host, err := manet.DialArgs(addr)
if err != nil {
log.Fatal("manet.DialArgs() failed: ", err)
}

if *verbose { // lower log level
logging.SetDebugLogging()
}

// construct url to dial
var u url.URL
u.Scheme = "http"
u.Host = host
u.Path = *endpoint

// show what we got
start := time.Now()
log.Debugf("starting at %s, tries: %d, timeout: %s, url: %s", start, *tries, *timeout, u)
log.Debugf("starting at %s, tries: %d, timeout: %s, addr: %s", start, *tries, *timeout, addr)

for *tries > 0 {

err := checkOK(http.Get(u.String()))
c, err := manet.Dial(addr)
if err == nil {
log.Debugf("ok - endpoint reachable with %d tries remaining, took %s", *tries, time.Since(start))
c.Close()
os.Exit(0)
}
log.Debug("get failed: ", err)
log.Debug("connect failed: ", err)
time.Sleep(*timeout)
*tries--
}

log.Error("failed.")
os.Exit(1)
}

func checkOK(resp *http.Response, err error) error {
if err == nil { // request worked
defer resp.Body.Close()
if resp.StatusCode == http.StatusOK {
return nil
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Fprintf(os.Stderr, "pollEndpoint: ioutil.ReadAll() Error: %s", err)
}
return fmt.Errorf("response not OK. %d %s %q", resp.StatusCode, resp.Status, string(body))
}
return err
}

0 comments on commit 7911711

Please sign in to comment.