Skip to content

Commit

Permalink
fix: Prevent Routing.Type=auto from enabling dhtserver mode if have t…
Browse files Browse the repository at this point in the history
…oo low of limits

Closes #9548

Signed-off-by: Antonio Navarro Perez <antnavper@gmail.com>
  • Loading branch information
ajnavarro committed Jan 18, 2023
1 parent b88d580 commit 635efcb
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 3 deletions.
19 changes: 19 additions & 0 deletions cmd/ipfs/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
fsrepo "github.com/ipfs/kubo/repo/fsrepo"
"github.com/ipfs/kubo/repo/fsrepo/migrations"
"github.com/ipfs/kubo/repo/fsrepo/migrations/ipfsfetcher"
dht "github.com/libp2p/go-libp2p-kad-dht"
p2pcrypto "github.com/libp2p/go-libp2p/core/crypto"
pnet "github.com/libp2p/go-libp2p/core/pnet"
sockets "github.com/libp2p/go-socket-activation"
Expand Down Expand Up @@ -408,14 +409,32 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment
}
}

// Check limits to see if we have enough to run DHT as a server.
sysConnInbound := cfg.Swarm.ResourceMgr.Limits.System.ConnsInbound
sysStreamInbound := cfg.Swarm.ResourceMgr.Limits.System.StreamsInbound
dhtLimits, ok := cfg.Swarm.ResourceMgr.Limits.Protocol[dht.ProtocolDHT]
var dhtStreamsInbound int
if ok {
dhtStreamsInbound = dhtLimits.StreamsInbound
}

switch routingOption {
case routingOptionSupernodeKwd:
return errors.New("supernode routing was never fully implemented and has been removed")
case routingOptionDefaultKwd, routingOptionAutoKwd:
mode := dht.ModeAuto
if (sysConnInbound != 0 && sysConnInbound <= config.DefaultResourceMgrMinInboundConns) ||
(sysStreamInbound != 0 && sysStreamInbound <= config.DefaultResourceMgrMinInboundConns) ||
(dhtStreamsInbound != 0 && dhtStreamsInbound <= config.DefaultResourceMgrMinInboundConns) {
mode = dht.ModeClient
fmt.Println("You don't have enough resources to run as a DHT server. Running as a DHT client instead.")
}

ncfg.Routing = libp2p.ConstructDefaultRouting(
cfg.Identity.PeerID,
cfg.Addresses.Swarm,
cfg.Identity.PrivKey,
mode,
)
case routingOptionDHTClientKwd:
ncfg.Routing = libp2p.DHTClientOption
Expand Down
4 changes: 2 additions & 2 deletions core/node/libp2p/routingopt.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func init() {
}

// ConstructDefaultRouting returns routers used when Routing.Type is unset or set to "auto"
func ConstructDefaultRouting(peerID string, addrs []string, privKey string) func(
func ConstructDefaultRouting(peerID string, addrs []string, privKey string, mode dht.ModeOpt) func(
ctx context.Context,
host host.Host,
dstore datastore.Batching,
Expand All @@ -59,7 +59,7 @@ func ConstructDefaultRouting(peerID string, addrs []string, privKey string) func
var routers []*routinghelpers.ParallelRouter

// Run the default DHT routing (same as Routing.Type = "dht")
dhtRouting, err := DHTOption(ctx, host, dstore, validator, bootstrapPeers...)
dhtRouting, err := constructDHTRouting(mode)(ctx, host, dstore, validator)
if err != nil {
return nil, err
}
Expand Down
54 changes: 53 additions & 1 deletion test/cli/delegated_routing_http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,67 @@ package cli
import (
"net/http"
"net/http/httptest"
"os/exec"
"strings"
"testing"
"time"

"github.com/ipfs/kubo/config"
"github.com/ipfs/kubo/test/cli/harness"
. "github.com/ipfs/kubo/test/cli/testutils"
dht "github.com/libp2p/go-libp2p-kad-dht"
"github.com/libp2p/go-libp2p/core/protocol"
rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestDelegatedRoutingLowResources(t *testing.T) {
t.Parallel()
node := harness.NewT(t).NewNode().Init()

node.UpdateConfig(func(cfg *config.Config) {
cfg.Swarm.ResourceMgr.Enabled = config.True
cfg.Swarm.ResourceMgr.Limits = &rcmgr.LimitConfig{
System: rcmgr.BaseLimit{
ConnsInbound: 10,
StreamsInbound: 10,
},
Protocol: map[protocol.ID]rcmgr.BaseLimit{
dht.ProtocolDHT: {
StreamsInbound: 10,
},
},
}
})

var cfgVal int
node.GetIPFSConfig("Swarm.ResourceMgr.Limits.System.ConnsInbound", &cfgVal)
require.Equal(t, 10, cfgVal)

res := node.Runner.MustRun(harness.RunRequest{
Path: node.IPFSBin,
RunFunc: (*exec.Cmd).Start,
Args: []string{"daemon"},
})

var checks int
for {
if checks == 20 {
require.Fail(t, "expected string not found")
}

for _, s := range res.Stdout.Lines() {
if strings.EqualFold(s, "You don't have enough resources to run as a DHT server. Running as a DHT client instead.") {
return
}
}

checks++
time.Sleep(1 * time.Second)
}
}

func TestHTTPDelegatedRouting(t *testing.T) {
t.Parallel()
node := harness.NewT(t).NewNode().Init().StartDaemon()
Expand Down Expand Up @@ -117,5 +170,4 @@ func TestHTTPDelegatedRouting(t *testing.T) {
res = node.IPFS("routing", "findprovs", findProvsCID)
assert.Equal(t, prov, res.Stdout.Trimmed())
})

}

0 comments on commit 635efcb

Please sign in to comment.