Skip to content

Commit

Permalink
[FAB-4867]: Add endpoint validation for gossip.
Browse files Browse the repository at this point in the history
While initializing gossip component for gossip service there is endpoint
parameter provided which later split into hostname and port number,
while there is no check whenever endpoint configured properly, hence
misconfiguration leads to panic with no meaninggful information about
the configuration error. This commit takes care of it by adding
validation.

Change-Id: I50fd728e715b40aa13b449e5867e3542cee67b1e
Signed-off-by: Artem Barger <bartem@il.ibm.com>
  • Loading branch information
C0rWin committed Jun 21, 2017
1 parent 3bc937e commit 90e09ea
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 32 deletions.
4 changes: 3 additions & 1 deletion core/peer/peer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,13 @@ func TestCreateChainFromBlock(t *testing.T) {
dialOpts = append(dialOpts, grpc.WithInsecure())
return dialOpts
}
service.InitGossipServiceCustomDeliveryFactory(
err = service.InitGossipServiceCustomDeliveryFactory(
identity, "localhost:13611", grpcServer,
&mockDeliveryClientFactory{},
messageCryptoService, secAdv, defaultSecureDialOpts)

assert.NoError(t, err)

err = CreateChainFromBlock(block)
if err != nil {
t.Fatalf("failed to create chain %s", err)
Expand Down
3 changes: 2 additions & 1 deletion core/scc/cscc/configure_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ func TestConfigerInvokeJoinChainCorrectParams(t *testing.T) {
identity, _ := mgmt.GetLocalSigningIdentityOrPanic().Serialize()
messageCryptoService := peergossip.NewMCS(&mocks.ChannelPolicyManagerGetter{}, localmsp.NewSigner(), mgmt.NewDeserializersManager())
secAdv := peergossip.NewSecurityAdvisor(mgmt.NewDeserializersManager())
service.InitGossipServiceCustomDeliveryFactory(identity, peerEndpoint, nil, &mockDeliveryClientFactory{}, messageCryptoService, secAdv, nil)
err := service.InitGossipServiceCustomDeliveryFactory(identity, peerEndpoint, nil, &mockDeliveryClientFactory{}, messageCryptoService, secAdv, nil)
assert.NoError(t, err)

// Successful path for JoinChain
blockBytes := mockConfigBlock()
Expand Down
28 changes: 19 additions & 9 deletions gossip/integration/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ package integration

import (
"crypto/tls"
"fmt"
"net"
"strconv"
"strings"
"time"

"github.com/hyperledger/fabric/core/config"
Expand All @@ -33,17 +34,23 @@ import (

// This file is used to bootstrap a gossip instance and/or leader election service instance

func newConfig(selfEndpoint string, externalEndpoint string, bootPeers ...string) *gossip.Config {
port, err := strconv.ParseInt(strings.Split(selfEndpoint, ":")[1], 10, 64)
func newConfig(selfEndpoint string, externalEndpoint string, bootPeers ...string) (*gossip.Config, error) {
_, p, err := net.SplitHostPort(selfEndpoint)

if err != nil {
return nil, fmt.Errorf("misconfigured endpoint %s, the error is %s", selfEndpoint, err)
}

port, err := strconv.ParseInt(p, 10, 64)
if err != nil {
panic(err)
return nil, fmt.Errorf("misconfigured endpoint %s, failed to parse port number due to %s", selfEndpoint, err)
}

var cert *tls.Certificate
if viper.GetBool("peer.tls.enabled") {
certTmp, err := tls.LoadX509KeyPair(config.GetPath("peer.tls.cert.file"), config.GetPath("peer.tls.key.file"))
if err != nil {
panic(err)
return nil, fmt.Errorf("failed to load certificates because of %s", err)
}
cert = &certTmp
}
Expand All @@ -66,19 +73,22 @@ func newConfig(selfEndpoint string, externalEndpoint string, bootPeers ...string
PublishStateInfoInterval: util.GetDurationOrDefault("peer.gossip.publishStateInfoInterval", 4*time.Second),
SkipBlockVerification: viper.GetBool("peer.gossip.skipBlockVerification"),
TLSServerCert: cert,
}
}, nil
}

// NewGossipComponent creates a gossip component that attaches itself to the given gRPC server
func NewGossipComponent(peerIdentity []byte, endpoint string, s *grpc.Server,
secAdv api.SecurityAdvisor, cryptSvc api.MessageCryptoService, idMapper identity.Mapper,
secureDialOpts api.PeerSecureDialOpts, bootPeers ...string) gossip.Gossip {
secureDialOpts api.PeerSecureDialOpts, bootPeers ...string) (gossip.Gossip, error) {

externalEndpoint := viper.GetString("peer.gossip.externalEndpoint")

conf := newConfig(endpoint, externalEndpoint, bootPeers...)
conf, err := newConfig(endpoint, externalEndpoint, bootPeers...)
if err != nil {
return nil, err
}
gossipInstance := gossip.NewGossipService(conf, s, secAdv, cryptSvc, idMapper,
peerIdentity, secureDialOpts)

return gossipInstance
return gossipInstance, nil
}
23 changes: 12 additions & 11 deletions gossip/integration/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,15 @@ func TestNewGossipCryptoService(t *testing.T) {
peerIdentity, _ := mgmt.GetLocalSigningIdentityOrPanic().Serialize()
idMapper := identity.NewIdentityMapper(cryptSvc, peerIdentity)

g1 := NewGossipComponent(peerIdentity, endpoint1, s1, secAdv, cryptSvc, idMapper,
g1, err := NewGossipComponent(peerIdentity, endpoint1, s1, secAdv, cryptSvc, idMapper,
defaultSecureDialOpts)
g2 := NewGossipComponent(peerIdentity, endpoint2, s2, secAdv, cryptSvc, idMapper,
assert.NoError(t, err)
g2, err := NewGossipComponent(peerIdentity, endpoint2, s2, secAdv, cryptSvc, idMapper,
defaultSecureDialOpts, endpoint1)
g3 := NewGossipComponent(peerIdentity, endpoint3, s3, secAdv, cryptSvc, idMapper,
assert.NoError(t, err)
g3, err := NewGossipComponent(peerIdentity, endpoint3, s3, secAdv, cryptSvc, idMapper,
defaultSecureDialOpts, endpoint1)
assert.NoError(t, err)
defer g1.Stop()
defer g2.Stop()
defer g3.Stop()
Expand All @@ -83,14 +86,12 @@ func TestBadInitialization(t *testing.T) {
peerIdentity, _ := mgmt.GetLocalSigningIdentityOrPanic().Serialize()
s1 := grpc.NewServer()
idMapper := identity.NewIdentityMapper(cryptSvc, peerIdentity)
assert.Panics(t, func() {
newConfig("anEndpointWithoutAPort", "anEndpointWithoutAPort")
})
assert.Panics(t, func() {
viper.Set("peer.tls.enabled", true)
NewGossipComponent(peerIdentity, "localhost:5000", s1, secAdv, cryptSvc, idMapper,
defaultSecureDialOpts)
})
_, err := newConfig("anEndpointWithoutAPort", "anEndpointWithoutAPort")

viper.Set("peer.tls.enabled", true)
_, err = NewGossipComponent(peerIdentity, "localhost:5000", s1, secAdv, cryptSvc, idMapper,
defaultSecureDialOpts)
assert.Error(t, err)
}

func setupTestEnv() {
Expand Down
11 changes: 7 additions & 4 deletions gossip/service/gossip_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,20 +120,22 @@ var logger = util.GetLogger(util.LoggingServiceModule, "")

// InitGossipService initialize gossip service
func InitGossipService(peerIdentity []byte, endpoint string, s *grpc.Server, mcs api.MessageCryptoService,
secAdv api.SecurityAdvisor, secureDialOpts api.PeerSecureDialOpts, bootPeers ...string) {
secAdv api.SecurityAdvisor, secureDialOpts api.PeerSecureDialOpts, bootPeers ...string) error {
// TODO: Remove this.
// TODO: This is a temporary work-around to make the gossip leader election module load its logger at startup
// TODO: in order for the flogging package to register this logger in time so it can set the log levels as requested in the config
util.GetLogger(util.LoggingElectionModule, "")
InitGossipServiceCustomDeliveryFactory(peerIdentity, endpoint, s, &deliveryFactoryImpl{},
return InitGossipServiceCustomDeliveryFactory(peerIdentity, endpoint, s, &deliveryFactoryImpl{},
mcs, secAdv, secureDialOpts, bootPeers...)
}

// InitGossipServiceCustomDeliveryFactory initialize gossip service with customize delivery factory
// implementation, might be useful for testing and mocking purposes
func InitGossipServiceCustomDeliveryFactory(peerIdentity []byte, endpoint string, s *grpc.Server,
factory DeliveryServiceFactory, mcs api.MessageCryptoService, secAdv api.SecurityAdvisor,
secureDialOpts api.PeerSecureDialOpts, bootPeers ...string) {
secureDialOpts api.PeerSecureDialOpts, bootPeers ...string) error {
var err error
var gossip gossip.Gossip
once.Do(func() {
if overrideEndpoint := viper.GetString("peer.gossip.endpoint"); overrideEndpoint != "" {
endpoint = overrideEndpoint
Expand All @@ -142,7 +144,7 @@ func InitGossipServiceCustomDeliveryFactory(peerIdentity []byte, endpoint string
logger.Info("Initialize gossip with endpoint", endpoint, "and bootstrap set", bootPeers)

idMapper := identity.NewIdentityMapper(mcs, peerIdentity)
gossip := integration.NewGossipComponent(peerIdentity, endpoint, s, secAdv,
gossip, err = integration.NewGossipComponent(peerIdentity, endpoint, s, secAdv,
mcs, idMapper, secureDialOpts, bootPeers...)
gossipServiceInstance = &gossipServiceImpl{
mcs: mcs,
Expand All @@ -155,6 +157,7 @@ func InitGossipServiceCustomDeliveryFactory(peerIdentity []byte, endpoint string
secAdv: secAdv,
}
})
return err
}

// GetGossipService returns an instance of gossip service
Expand Down
12 changes: 7 additions & 5 deletions gossip/service/gossip_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,12 @@ func TestInitGossipService(t *testing.T) {
wg.Add(10)
for i := 0; i < 10; i++ {
go func() {
defer wg.Done()
messageCryptoService := peergossip.NewMCS(&mocks.ChannelPolicyManagerGetter{}, localmsp.NewSigner(), mgmt.NewDeserializersManager())
secAdv := peergossip.NewSecurityAdvisor(mgmt.NewDeserializersManager())
InitGossipService(identity, "localhost:5611", grpcServer, messageCryptoService,
err := InitGossipService(identity, "localhost:5611", grpcServer, messageCryptoService,
secAdv, nil)

wg.Done()
assert.NoError(t, err)
}()
}
wg.Wait()
Expand Down Expand Up @@ -703,8 +703,9 @@ func TestInvalidInitialization(t *testing.T) {
defer grpcServer.Stop()

secAdv := peergossip.NewSecurityAdvisor(mgmt.NewDeserializersManager())
InitGossipService(api.PeerIdentityType("IDENTITY"), "localhost:7611", grpcServer,
err := InitGossipService(api.PeerIdentityType("IDENTITY"), "localhost:7611", grpcServer,
&naiveCryptoService{}, secAdv, nil)
assert.NoError(t, err)
gService := GetGossipService().(*gossipServiceImpl)
defer gService.Stop()

Expand All @@ -727,8 +728,9 @@ func TestChannelConfig(t *testing.T) {
defer grpcServer.Stop()

secAdv := peergossip.NewSecurityAdvisor(mgmt.NewDeserializersManager())
InitGossipService(api.PeerIdentityType("IDENTITY"), "localhost:6611", grpcServer,
error = InitGossipService(api.PeerIdentityType("IDENTITY"), "localhost:6611", grpcServer,
&naiveCryptoService{}, secAdv, nil)
assert.NoError(t, error)
gService := GetGossipService().(*gossipServiceImpl)
defer gService.Stop()

Expand Down
5 changes: 4 additions & 1 deletion peer/node/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,11 @@ func serve(args []string) error {
}
return dialOpts
}
service.InitGossipService(serializedIdentity, peerEndpoint.Address, peerServer.Server(),
err = service.InitGossipService(serializedIdentity, peerEndpoint.Address, peerServer.Server(),
messageCryptoService, secAdv, secureDialOpts, bootstrap...)
if err != nil {
return err
}
defer service.GetGossipService().Stop()

//initialize system chaincodes
Expand Down

0 comments on commit 90e09ea

Please sign in to comment.