From 95beedb679ef29c8c5e094d3807ff157b0a2b37e Mon Sep 17 00:00:00 2001 From: Kishan Mohanbhai Sagathiya Date: Fri, 13 Dec 2019 23:48:34 +0530 Subject: [PATCH] Add Announce and NoAnnounce swarm options Same as corresponding IPFS Options announce - the swarm addresses to announce to the network no_announce - swarm addresses not to announce to the network --- cluster_config.go | 40 +++++++++++++++++++++++++++++++--------- clusterhost.go | 47 +++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 2 ++ go.sum | 4 ++++ util.go | 22 ++++++++++++++++++++++ 5 files changed, 106 insertions(+), 9 deletions(-) diff --git a/cluster_config.go b/cluster_config.go index 0cc81e1f..817f441f 100644 --- a/cluster_config.go +++ b/cluster_config.go @@ -94,6 +94,13 @@ type Config struct { // peers. DialPeerTimeout time.Duration + // If non-empty, this array specifies the swarm addresses to announce to + // the network. If empty, the daemon will announce inferred swarm addresses. + Announce []ma.Multiaddr + + // Array of swarm addresses not to announce to the network. + NoAnnounce []ma.Multiaddr + // Time between syncs of the consensus state to the // tracker state. Normally states are synced anyway, but this helps // when new nodes are joining the cluster. Reduce for faster @@ -182,6 +189,8 @@ type configJSON struct { EnableRelayHop bool `json:"enable_relay_hop"` ConnectionManager *connMgrConfigJSON `json:"connection_manager"` DialPeerTimeout string `json:"dial_peer_timeout"` + Announce []string `json:"announce"` + NoAnnounce []string `json:"no_announce"` StateSyncInterval string `json:"state_sync_interval"` PinRecoverInterval string `json:"pin_recover_interval"` ReplicationFactorMin int `json:"replication_factor_min"` @@ -379,6 +388,8 @@ func (cfg *Config) setDefaults() { GracePeriod: DefaultConnMgrGracePeriod, } cfg.DialPeerTimeout = DefaultDialPeerTimeout + cfg.Announce = []ma.Multiaddr{} + cfg.NoAnnounce = []ma.Multiaddr{} cfg.LeaveOnShutdown = DefaultLeaveOnShutdown cfg.StateSyncInterval = DefaultStateSyncInterval cfg.PinRecoverInterval = DefaultPinRecoverInterval @@ -424,16 +435,11 @@ func (cfg *Config) applyConfigJSON(jcfg *configJSON) error { } cfg.Secret = clusterSecret - var listenAddrs []ma.Multiaddr - for _, addr := range jcfg.ListenMultiaddress { - listenAddr, err := ma.NewMultiaddr(addr) - if err != nil { - err = fmt.Errorf("error parsing a listen_multiaddress: %s", err) - return err - } - listenAddrs = append(listenAddrs, listenAddr) + listenAddrs, err := toMultiAddrs(jcfg.ListenMultiaddress) + if err != nil { + err = fmt.Errorf("error parsing listen_multiaddress: %s", err) + return err } - cfg.ListenAddr = listenAddrs cfg.EnableRelayHop = jcfg.EnableRelayHop if conman := jcfg.ConnectionManager; conman != nil { @@ -449,6 +455,20 @@ func (cfg *Config) applyConfigJSON(jcfg *configJSON) error { } } + annAddrs, err := toMultiAddrs(jcfg.Announce) + if err != nil { + err = fmt.Errorf("error parsing announce: %s", err) + return err + } + cfg.Announce = annAddrs + + noAnnAddrs, err := toMultiAddrs(jcfg.NoAnnounce) + if err != nil { + err = fmt.Errorf("error parsing no_announce: %s", err) + return err + } + cfg.NoAnnounce = noAnnAddrs + rplMin := jcfg.ReplicationFactorMin rplMax := jcfg.ReplicationFactorMax config.SetIfNotDefault(rplMin, &cfg.ReplicationFactorMin) @@ -525,6 +545,8 @@ func (cfg *Config) toConfigJSON() (jcfg *configJSON, err error) { GracePeriod: cfg.ConnMgr.GracePeriod.String(), } jcfg.DialPeerTimeout = cfg.DialPeerTimeout.String() + jcfg.Announce = multiAddrstoStrings(cfg.Announce) + jcfg.NoAnnounce = multiAddrstoStrings(cfg.NoAnnounce) jcfg.StateSyncInterval = cfg.StateSyncInterval.String() jcfg.PinRecoverInterval = cfg.PinRecoverInterval.String() jcfg.MonitorPingInterval = cfg.MonitorPingInterval.String() diff --git a/clusterhost.go b/clusterhost.go index e6885237..c383abb8 100644 --- a/clusterhost.go +++ b/clusterhost.go @@ -20,6 +20,7 @@ import ( corepnet "github.com/libp2p/go-libp2p/core/pnet" routing "github.com/libp2p/go-libp2p/core/routing" "github.com/libp2p/go-libp2p/p2p/host/autorelay" + p2pbhost "github.com/libp2p/go-libp2p/p2p/host/basic" connmgr "github.com/libp2p/go-libp2p/p2p/net/connmgr" identify "github.com/libp2p/go-libp2p/p2p/protocol/identify" noise "github.com/libp2p/go-libp2p/p2p/security/noise" @@ -27,6 +28,9 @@ import ( libp2pquic "github.com/libp2p/go-libp2p/p2p/transport/quic" tcp "github.com/libp2p/go-libp2p/p2p/transport/tcp" websocket "github.com/libp2p/go-libp2p/p2p/transport/websocket" + mafilter "github.com/libp2p/go-maddr-filter" + ma "github.com/multiformats/go-multiaddr" + mamask "github.com/whyrusleeping/multiaddr-filter" ) const dhtNamespace = "dht" @@ -84,8 +88,14 @@ func NewClusterHost( return idht } + addrsFactory, err := makeAddrsFactory(cfg.Announce, cfg.NoAnnounce) + if err != nil { + return nil, nil, nil, err + } + opts := []libp2p.Option{ libp2p.ListenAddrs(cfg.ListenAddr...), + libp2p.AddrsFactory(addrsFactory), libp2p.NATPortMap(), libp2p.ConnectionManager(connman), libp2p.Routing(func(h host.Host) (routing.PeerRouting, error) { @@ -240,3 +250,40 @@ func newPeerSource(hostGetter func() host.Host, dhtGetter func() *dual.DHT) auto func EncodeProtectorKey(secretBytes []byte) string { return hex.EncodeToString(secretBytes) } + +func makeAddrsFactory(announce []ma.Multiaddr, noAnnounce []ma.Multiaddr) (p2pbhost.AddrsFactory, error) { + filters := mafilter.NewFilters() + noAnnAddrs := map[string]bool{} + for _, addr := range multiAddrstoStrings(noAnnounce) { + f, err := mamask.NewMask(addr) + if err == nil { + filters.AddFilter(*f, mafilter.ActionDeny) + continue + } + maddr, err := ma.NewMultiaddr(addr) + if err != nil { + return nil, err + } + noAnnAddrs[string(maddr.Bytes())] = true + } + + return func(allAddrs []ma.Multiaddr) []ma.Multiaddr { + var addrs []ma.Multiaddr + if len(announce) > 0 { + addrs = announce + } else { + addrs = allAddrs + } + + var out []ma.Multiaddr + for _, maddr := range addrs { + // check for exact matches + ok := noAnnAddrs[string(maddr.Bytes())] + // check for /ipcidr matches + if !ok && !filters.AddrBlocked(maddr) { + out = append(out, maddr) + } + } + return out + }, nil +} diff --git a/go.mod b/go.mod index 67a8dec8..547c3ff3 100644 --- a/go.mod +++ b/go.mod @@ -150,6 +150,7 @@ require ( github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect github.com/libp2p/go-libp2p-routing-helpers v0.7.2 // indirect + github.com/libp2p/go-maddr-filter v0.1.0 github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.2.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect @@ -193,6 +194,7 @@ require ( github.com/whyrusleeping/cbor-gen v0.0.0-20230818171029-f91ae536ca25 // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect + github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect go.opentelemetry.io/otel v1.16.0 // indirect go.opentelemetry.io/otel/metric v1.16.0 // indirect diff --git a/go.sum b/go.sum index faba036b..a13660a8 100644 --- a/go.sum +++ b/go.sum @@ -584,6 +584,8 @@ github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-maddr-filter v0.1.0 h1:4ACqZKw8AqiuJfwFGq1CYDFugfXTOos+qQ3DETkhtCE= +github.com/libp2p/go-maddr-filter v0.1.0/go.mod h1:VzZhTXkMucEGGEOSKddrwGiOv0tUhgnKqNEmIAz/bPU= github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= @@ -671,6 +673,7 @@ github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lg github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= +github.com/multiformats/go-multiaddr v0.2.2/go.mod h1:NtfXiOtHvghW9KojvtySjH5y0u0xW5UouOmQQrn6a3Y= github.com/multiformats/go-multiaddr v0.11.0 h1:XqGyJ8ufbCE0HmTDwx2kPdsrQ36AGPZNZX6s6xfJH10= github.com/multiformats/go-multiaddr v0.11.0/go.mod h1:gWUm0QLR4thQ6+ZF6SXUw8YjtwQSPapICM+NmCkxHSM= github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= @@ -900,6 +903,7 @@ github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1 github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h1:cZNvX9cFybI01GriPRMXDtczuvUhgbcYr9iCGaNlRv8= github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= diff --git a/util.go b/util.go index e039c6b2..8552c5ba 100644 --- a/util.go +++ b/util.go @@ -209,3 +209,25 @@ func publicIPFSAddresses(in []api.Multiaddr) []api.Multiaddr { } return out } + +func toMultiAddrs(addrs []string) ([]ma.Multiaddr, error) { + var mAddrs []ma.Multiaddr + for _, addr := range addrs { + mAddr, err := ma.NewMultiaddr(addr) + if err != nil { + return nil, err + } + mAddrs = append(mAddrs, mAddr) + } + + return mAddrs, nil +} + +func multiAddrstoStrings(mAddrs []ma.Multiaddr) []string { + var addrs []string + for _, addr := range mAddrs { + addrs = append(addrs, addr.String()) + } + + return addrs +}