github.com/Hnampk/fabric@v2.1.1+incompatible/gossip/discovery/discovery_impl.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package discovery
     8  
     9  import (
    10  	"bytes"
    11  	"fmt"
    12  	"math"
    13  	"strconv"
    14  	"strings"
    15  	"sync"
    16  	"time"
    17  
    18  	proto "github.com/hyperledger/fabric-protos-go/gossip"
    19  	"github.com/hyperledger/fabric/gossip/common"
    20  	"github.com/hyperledger/fabric/gossip/gossip/msgstore"
    21  	"github.com/hyperledger/fabric/gossip/protoext"
    22  	"github.com/hyperledger/fabric/gossip/util"
    23  	"github.com/pkg/errors"
    24  )
    25  
    26  const DefAliveTimeInterval = 5 * time.Second
    27  const DefAliveExpirationTimeout = 5 * DefAliveTimeInterval
    28  const DefAliveExpirationCheckInterval = DefAliveExpirationTimeout / 10
    29  const DefReconnectInterval = DefAliveExpirationTimeout
    30  const msgExpirationFactor = 20
    31  
    32  var maxConnectionAttempts = 120
    33  
    34  // SetMaxConnAttempts sets the maximum number of connection
    35  // attempts the peer would perform when invoking Connect()
    36  func SetMaxConnAttempts(attempts int) {
    37  	maxConnectionAttempts = attempts
    38  }
    39  
    40  type timestamp struct {
    41  	incTime  time.Time
    42  	seqNum   uint64
    43  	lastSeen time.Time
    44  }
    45  
    46  func (ts *timestamp) String() string {
    47  	return fmt.Sprintf("%v, %v", ts.incTime.UnixNano(), ts.seqNum)
    48  }
    49  
    50  type gossipDiscoveryImpl struct {
    51  	incTime          uint64
    52  	seqNum           uint64
    53  	self             NetworkMember
    54  	deadLastTS       map[string]*timestamp     // H
    55  	aliveLastTS      map[string]*timestamp     // V
    56  	id2Member        map[string]*NetworkMember // all known members
    57  	aliveMembership  *util.MembershipStore
    58  	deadMembership   *util.MembershipStore
    59  	selfAliveMessage *protoext.SignedGossipMessage
    60  
    61  	msgStore *aliveMsgStore
    62  
    63  	comm  CommService
    64  	crypt CryptoService
    65  	lock  *sync.RWMutex
    66  
    67  	toDieChan        chan struct{}
    68  	port             int
    69  	logger           util.Logger
    70  	disclosurePolicy DisclosurePolicy
    71  	pubsub           *util.PubSub
    72  
    73  	aliveTimeInterval            time.Duration
    74  	aliveExpirationTimeout       time.Duration
    75  	aliveExpirationCheckInterval time.Duration
    76  	reconnectInterval            time.Duration
    77  
    78  	bootstrapPeers []string
    79  }
    80  
    81  type DiscoveryConfig struct {
    82  	AliveTimeInterval            time.Duration
    83  	AliveExpirationTimeout       time.Duration
    84  	AliveExpirationCheckInterval time.Duration
    85  	ReconnectInterval            time.Duration
    86  	BootstrapPeers               []string
    87  }
    88  
    89  // NewDiscoveryService returns a new discovery service with the comm module passed and the crypto service passed
    90  func NewDiscoveryService(self NetworkMember, comm CommService, crypt CryptoService, disPol DisclosurePolicy,
    91  	config DiscoveryConfig) Discovery {
    92  	d := &gossipDiscoveryImpl{
    93  		self:             self,
    94  		incTime:          uint64(time.Now().UnixNano()),
    95  		seqNum:           uint64(0),
    96  		deadLastTS:       make(map[string]*timestamp),
    97  		aliveLastTS:      make(map[string]*timestamp),
    98  		id2Member:        make(map[string]*NetworkMember),
    99  		aliveMembership:  util.NewMembershipStore(),
   100  		deadMembership:   util.NewMembershipStore(),
   101  		crypt:            crypt,
   102  		comm:             comm,
   103  		lock:             &sync.RWMutex{},
   104  		toDieChan:        make(chan struct{}),
   105  		logger:           util.GetLogger(util.DiscoveryLogger, self.InternalEndpoint),
   106  		disclosurePolicy: disPol,
   107  		pubsub:           util.NewPubSub(),
   108  
   109  		aliveTimeInterval:            config.AliveTimeInterval,
   110  		aliveExpirationTimeout:       config.AliveExpirationTimeout,
   111  		aliveExpirationCheckInterval: config.AliveExpirationCheckInterval,
   112  		reconnectInterval:            config.ReconnectInterval,
   113  
   114  		bootstrapPeers: config.BootstrapPeers,
   115  	}
   116  
   117  	d.validateSelfConfig()
   118  	d.msgStore = newAliveMsgStore(d)
   119  
   120  	go d.periodicalSendAlive()
   121  	go d.periodicalCheckAlive()
   122  	go d.handleMessages()
   123  	go d.periodicalReconnectToDead()
   124  	go d.handleEvents()
   125  
   126  	return d
   127  }
   128  
   129  // Lookup returns a network member, or nil if not found
   130  func (d *gossipDiscoveryImpl) Lookup(PKIID common.PKIidType) *NetworkMember {
   131  	if bytes.Equal(PKIID, d.self.PKIid) {
   132  		return &d.self
   133  	}
   134  	d.lock.RLock()
   135  	defer d.lock.RUnlock()
   136  	return copyNetworkMember(d.id2Member[string(PKIID)])
   137  }
   138  
   139  func (d *gossipDiscoveryImpl) Connect(member NetworkMember, id identifier) {
   140  	for _, endpoint := range []string{member.InternalEndpoint, member.Endpoint} {
   141  		if d.isMyOwnEndpoint(endpoint) {
   142  			d.logger.Debug("Skipping connecting to myself")
   143  			return
   144  		}
   145  	}
   146  
   147  	d.logger.Debug("Entering", member)
   148  	defer d.logger.Debug("Exiting")
   149  	go func() {
   150  		for i := 0; i < maxConnectionAttempts && !d.toDie(); i++ {
   151  			id, err := id()
   152  			if err != nil {
   153  				if d.toDie() {
   154  					return
   155  				}
   156  				d.logger.Warningf("Could not connect to %v : %v", member, err)
   157  				time.Sleep(d.reconnectInterval)
   158  				continue
   159  			}
   160  			peer := &NetworkMember{
   161  				InternalEndpoint: member.InternalEndpoint,
   162  				Endpoint:         member.Endpoint,
   163  				PKIid:            id.ID,
   164  			}
   165  			m, err := d.createMembershipRequest(id.SelfOrg)
   166  			if err != nil {
   167  				d.logger.Warningf("Failed creating membership request: %+v", errors.WithStack(err))
   168  				continue
   169  			}
   170  			req, err := protoext.NoopSign(m)
   171  			if err != nil {
   172  				d.logger.Warningf("Failed creating SignedGossipMessage: %+v", errors.WithStack(err))
   173  				continue
   174  			}
   175  			req.Nonce = util.RandomUInt64()
   176  			req, err = protoext.NoopSign(req.GossipMessage)
   177  			if err != nil {
   178  				d.logger.Warningf("Failed adding NONCE to SignedGossipMessage %+v", errors.WithStack(err))
   179  				continue
   180  			}
   181  			go d.sendUntilAcked(peer, req)
   182  			return
   183  		}
   184  
   185  	}()
   186  }
   187  
   188  func (d *gossipDiscoveryImpl) isMyOwnEndpoint(endpoint string) bool {
   189  	return endpoint == fmt.Sprintf("127.0.0.1:%d", d.port) || endpoint == fmt.Sprintf("localhost:%d", d.port) ||
   190  		endpoint == d.self.InternalEndpoint || endpoint == d.self.Endpoint
   191  }
   192  
   193  func (d *gossipDiscoveryImpl) validateSelfConfig() {
   194  	endpoint := d.self.InternalEndpoint
   195  	if len(endpoint) == 0 {
   196  		d.logger.Panic("Internal endpoint is empty:", endpoint)
   197  	}
   198  
   199  	internalEndpointSplit := strings.Split(endpoint, ":")
   200  	if len(internalEndpointSplit) != 2 {
   201  		d.logger.Panicf("Self endpoint %s isn't formatted as 'host:port'", endpoint)
   202  	}
   203  	myPort, err := strconv.ParseInt(internalEndpointSplit[1], 10, 64)
   204  	if err != nil {
   205  		d.logger.Panicf("Self endpoint %s has not valid port, %+v", endpoint, errors.WithStack(err))
   206  	}
   207  
   208  	if myPort > int64(math.MaxUint16) {
   209  		d.logger.Panicf("Self endpoint %s's port takes more than 16 bits", endpoint)
   210  	}
   211  
   212  	d.port = int(myPort)
   213  }
   214  
   215  func (d *gossipDiscoveryImpl) sendUntilAcked(peer *NetworkMember, message *protoext.SignedGossipMessage) {
   216  	nonce := message.Nonce
   217  	for i := 0; i < maxConnectionAttempts && !d.toDie(); i++ {
   218  		sub := d.pubsub.Subscribe(fmt.Sprintf("%d", nonce), time.Second*5)
   219  		d.comm.SendToPeer(peer, message)
   220  		if _, timeoutErr := sub.Listen(); timeoutErr == nil {
   221  			return
   222  		}
   223  		time.Sleep(d.reconnectInterval)
   224  	}
   225  }
   226  
   227  func (d *gossipDiscoveryImpl) InitiateSync(peerNum int) {
   228  	if d.toDie() {
   229  		return
   230  	}
   231  	var peers2SendTo []*NetworkMember
   232  	m, err := d.createMembershipRequest(true)
   233  	if err != nil {
   234  		d.logger.Warningf("Failed creating membership request: %+v", errors.WithStack(err))
   235  		return
   236  	}
   237  	memReq, err := protoext.NoopSign(m)
   238  	if err != nil {
   239  		d.logger.Warningf("Failed creating SignedGossipMessage: %+v", errors.WithStack(err))
   240  		return
   241  	}
   242  	d.lock.RLock()
   243  
   244  	n := d.aliveMembership.Size()
   245  	k := peerNum
   246  	if k > n {
   247  		k = n
   248  	}
   249  
   250  	aliveMembersAsSlice := d.aliveMembership.ToSlice()
   251  	for _, i := range util.GetRandomIndices(k, n-1) {
   252  		pulledPeer := aliveMembersAsSlice[i].GetAliveMsg().Membership
   253  		var internalEndpoint string
   254  		if aliveMembersAsSlice[i].Envelope.SecretEnvelope != nil {
   255  			internalEndpoint = protoext.InternalEndpoint(aliveMembersAsSlice[i].Envelope.SecretEnvelope)
   256  		}
   257  		netMember := &NetworkMember{
   258  			Endpoint:         pulledPeer.Endpoint,
   259  			Metadata:         pulledPeer.Metadata,
   260  			PKIid:            pulledPeer.PkiId,
   261  			InternalEndpoint: internalEndpoint,
   262  		}
   263  		peers2SendTo = append(peers2SendTo, netMember)
   264  	}
   265  
   266  	d.lock.RUnlock()
   267  
   268  	for _, netMember := range peers2SendTo {
   269  		d.comm.SendToPeer(netMember, memReq)
   270  	}
   271  }
   272  
   273  func (d *gossipDiscoveryImpl) handleEvents() {
   274  	defer d.logger.Debug("Stopped")
   275  
   276  	for {
   277  		select {
   278  		case deadPeer := <-d.comm.PresumedDead():
   279  			if d.isAlive(deadPeer) {
   280  				d.expireDeadMembers([]common.PKIidType{deadPeer})
   281  			}
   282  		case changedPKIID := <-d.comm.IdentitySwitch():
   283  			// If a peer changed its PKI-ID, purge the old PKI-ID
   284  			d.purge(changedPKIID)
   285  		case <-d.toDieChan:
   286  			return
   287  		}
   288  	}
   289  }
   290  
   291  func (d *gossipDiscoveryImpl) isAlive(pkiID common.PKIidType) bool {
   292  	d.lock.RLock()
   293  	defer d.lock.RUnlock()
   294  	_, alive := d.aliveLastTS[string(pkiID)]
   295  	return alive
   296  }
   297  
   298  func (d *gossipDiscoveryImpl) handleMessages() {
   299  	defer d.logger.Debug("Stopped")
   300  
   301  	in := d.comm.Accept()
   302  	for {
   303  		select {
   304  		case m := <-in:
   305  			d.handleMsgFromComm(m)
   306  		case <-d.toDieChan:
   307  			return
   308  		}
   309  	}
   310  }
   311  
   312  func (d *gossipDiscoveryImpl) handleMsgFromComm(msg protoext.ReceivedMessage) {
   313  	if msg == nil {
   314  		return
   315  	}
   316  	m := msg.GetGossipMessage()
   317  	if m.GetAliveMsg() == nil && m.GetMemRes() == nil && m.GetMemReq() == nil {
   318  		d.logger.Warning("Got message with wrong type (expected Alive or MembershipResponse or MembershipRequest message):", m.GossipMessage)
   319  		return
   320  	}
   321  
   322  	d.logger.Debug("Got message:", m)
   323  	defer d.logger.Debug("Exiting")
   324  
   325  	if memReq := m.GetMemReq(); memReq != nil {
   326  		selfInfoGossipMsg, err := protoext.EnvelopeToGossipMessage(memReq.SelfInformation)
   327  		if err != nil {
   328  			d.logger.Warningf("Failed deserializing GossipMessage from envelope: %+v", errors.WithStack(err))
   329  			return
   330  		}
   331  
   332  		if !d.crypt.ValidateAliveMsg(selfInfoGossipMsg) {
   333  			return
   334  		}
   335  
   336  		if d.msgStore.CheckValid(selfInfoGossipMsg) {
   337  			d.handleAliveMessage(selfInfoGossipMsg)
   338  		}
   339  
   340  		var internalEndpoint string
   341  		if m.Envelope.SecretEnvelope != nil {
   342  			internalEndpoint = protoext.InternalEndpoint(m.Envelope.SecretEnvelope)
   343  		}
   344  
   345  		// Sending a membership response to a peer may block this routine
   346  		// in case the sending is deliberately slow (i.e attack).
   347  		// will keep this async until I'll write a timeout detector in the comm layer
   348  		go d.sendMemResponse(selfInfoGossipMsg.GetAliveMsg().Membership, internalEndpoint, m.Nonce)
   349  		return
   350  	}
   351  
   352  	if protoext.IsAliveMsg(m.GossipMessage) {
   353  		if !d.msgStore.CheckValid(m) || !d.crypt.ValidateAliveMsg(m) {
   354  			return
   355  		}
   356  		// If the message was sent by me, ignore it and don't forward it further
   357  		if d.isSentByMe(m) {
   358  			return
   359  		}
   360  
   361  		d.msgStore.Add(m)
   362  		d.handleAliveMessage(m)
   363  		d.comm.Forward(msg)
   364  		return
   365  	}
   366  
   367  	if memResp := m.GetMemRes(); memResp != nil {
   368  		d.pubsub.Publish(fmt.Sprintf("%d", m.Nonce), m.Nonce)
   369  		for _, env := range memResp.Alive {
   370  			am, err := protoext.EnvelopeToGossipMessage(env)
   371  			if err != nil {
   372  				d.logger.Warningf("Membership response contains an invalid message from an online peer:%+v", errors.WithStack(err))
   373  				return
   374  			}
   375  			if !protoext.IsAliveMsg(am.GossipMessage) {
   376  				d.logger.Warning("Expected alive message, got", am, "instead")
   377  				return
   378  			}
   379  
   380  			if d.msgStore.CheckValid(am) && d.crypt.ValidateAliveMsg(am) {
   381  				d.handleAliveMessage(am)
   382  			}
   383  		}
   384  
   385  		for _, env := range memResp.Dead {
   386  			dm, err := protoext.EnvelopeToGossipMessage(env)
   387  			if err != nil {
   388  				d.logger.Warningf("Membership response contains an invalid message from an offline peer %+v", errors.WithStack(err))
   389  				return
   390  			}
   391  
   392  			// Newer alive message exists or the message isn't authentic
   393  			if !d.msgStore.CheckValid(dm) || !d.crypt.ValidateAliveMsg(dm) {
   394  				continue
   395  			}
   396  
   397  			newDeadMembers := []*protoext.SignedGossipMessage{}
   398  			d.lock.RLock()
   399  			if _, known := d.id2Member[string(dm.GetAliveMsg().Membership.PkiId)]; !known {
   400  				newDeadMembers = append(newDeadMembers, dm)
   401  			}
   402  			d.lock.RUnlock()
   403  			d.learnNewMembers([]*protoext.SignedGossipMessage{}, newDeadMembers)
   404  		}
   405  	}
   406  }
   407  
   408  func (d *gossipDiscoveryImpl) sendMemResponse(targetMember *proto.Member, internalEndpoint string, nonce uint64) {
   409  	d.logger.Debug("Entering", protoext.MemberToString(targetMember))
   410  
   411  	targetPeer := &NetworkMember{
   412  		Endpoint:         targetMember.Endpoint,
   413  		Metadata:         targetMember.Metadata,
   414  		PKIid:            targetMember.PkiId,
   415  		InternalEndpoint: internalEndpoint,
   416  	}
   417  
   418  	var aliveMsg *protoext.SignedGossipMessage
   419  	var err error
   420  	d.lock.RLock()
   421  	aliveMsg = d.selfAliveMessage
   422  	d.lock.RUnlock()
   423  	if aliveMsg == nil {
   424  		aliveMsg, err = d.createSignedAliveMessage(true)
   425  		if err != nil {
   426  			d.logger.Warningf("Failed creating alive message: %+v", errors.WithStack(err))
   427  			return
   428  		}
   429  	}
   430  	memResp := d.createMembershipResponse(aliveMsg, targetPeer)
   431  	if memResp == nil {
   432  		errMsg := `Got a membership request from a peer that shouldn't have sent one: %v, closing connection to the peer as a result.`
   433  		d.logger.Warningf(errMsg, targetMember)
   434  		d.comm.CloseConn(targetPeer)
   435  		return
   436  	}
   437  
   438  	defer d.logger.Debug("Exiting, replying with", protoext.MembershipResponseToString(memResp))
   439  
   440  	msg, err := protoext.NoopSign(&proto.GossipMessage{
   441  		Tag:   proto.GossipMessage_EMPTY,
   442  		Nonce: nonce,
   443  		Content: &proto.GossipMessage_MemRes{
   444  			MemRes: memResp,
   445  		},
   446  	})
   447  	if err != nil {
   448  		err = errors.WithStack(err)
   449  		d.logger.Warningf("Failed creating SignedGossipMessage: %+v", errors.WithStack(err))
   450  		return
   451  	}
   452  	d.comm.SendToPeer(targetPeer, msg)
   453  }
   454  
   455  func (d *gossipDiscoveryImpl) createMembershipResponse(aliveMsg *protoext.SignedGossipMessage, targetMember *NetworkMember) *proto.MembershipResponse {
   456  	shouldBeDisclosed, omitConcealedFields := d.disclosurePolicy(targetMember)
   457  
   458  	if !shouldBeDisclosed(aliveMsg) {
   459  		return nil
   460  	}
   461  
   462  	d.lock.RLock()
   463  	defer d.lock.RUnlock()
   464  
   465  	deadPeers := []*proto.Envelope{}
   466  
   467  	for _, dm := range d.deadMembership.ToSlice() {
   468  
   469  		if !shouldBeDisclosed(dm) {
   470  			continue
   471  		}
   472  		deadPeers = append(deadPeers, omitConcealedFields(dm))
   473  	}
   474  
   475  	var aliveSnapshot []*proto.Envelope
   476  	for _, am := range d.aliveMembership.ToSlice() {
   477  		if !shouldBeDisclosed(am) {
   478  			continue
   479  		}
   480  		aliveSnapshot = append(aliveSnapshot, omitConcealedFields(am))
   481  	}
   482  
   483  	return &proto.MembershipResponse{
   484  		Alive: append(aliveSnapshot, omitConcealedFields(aliveMsg)),
   485  		Dead:  deadPeers,
   486  	}
   487  }
   488  
   489  func (d *gossipDiscoveryImpl) handleAliveMessage(m *protoext.SignedGossipMessage) {
   490  	d.logger.Debug("Entering", m)
   491  	defer d.logger.Debug("Exiting")
   492  
   493  	if d.isSentByMe(m) {
   494  		return
   495  	}
   496  
   497  	pkiID := m.GetAliveMsg().Membership.PkiId
   498  
   499  	ts := m.GetAliveMsg().Timestamp
   500  
   501  	d.lock.RLock()
   502  	_, known := d.id2Member[string(pkiID)]
   503  	d.lock.RUnlock()
   504  
   505  	if !known {
   506  		d.learnNewMembers([]*protoext.SignedGossipMessage{m}, []*protoext.SignedGossipMessage{})
   507  		return
   508  	}
   509  
   510  	d.lock.RLock()
   511  	_, isAlive := d.aliveLastTS[string(pkiID)]
   512  	lastDeadTS, isDead := d.deadLastTS[string(pkiID)]
   513  	d.lock.RUnlock()
   514  
   515  	if !isAlive && !isDead {
   516  		d.logger.Panicf("Member %s is known but not found neither in alive nor in dead lastTS maps, isAlive=%v, isDead=%v", m.GetAliveMsg().Membership.Endpoint, isAlive, isDead)
   517  		return
   518  	}
   519  
   520  	if isAlive && isDead {
   521  		d.logger.Panicf("Member %s is both alive and dead at the same time", m.GetAliveMsg().Membership)
   522  		return
   523  	}
   524  
   525  	if isDead {
   526  		if before(lastDeadTS, ts) {
   527  			// resurrect peer
   528  			d.resurrectMember(m, *ts)
   529  		} else if !same(lastDeadTS, ts) {
   530  			d.logger.Debug("got old alive message about dead peer ", protoext.MemberToString(m.GetAliveMsg().Membership), "lastDeadTS:", lastDeadTS, "but got ts:", ts)
   531  		}
   532  		return
   533  	}
   534  
   535  	d.lock.RLock()
   536  	lastAliveTS, isAlive := d.aliveLastTS[string(pkiID)]
   537  	d.lock.RUnlock()
   538  
   539  	if isAlive {
   540  		if before(lastAliveTS, ts) {
   541  			d.learnExistingMembers([]*protoext.SignedGossipMessage{m})
   542  		} else if !same(lastAliveTS, ts) {
   543  			d.logger.Debug("got old alive message about alive peer ", protoext.MemberToString(m.GetAliveMsg().Membership), "lastAliveTS:", lastAliveTS, "but got ts:", ts)
   544  		}
   545  
   546  	}
   547  	// else, ignore the message because it is too old
   548  }
   549  
   550  func (d *gossipDiscoveryImpl) purge(id common.PKIidType) {
   551  	d.logger.Infof("Purging %s from membership", id)
   552  	d.lock.Lock()
   553  	defer d.lock.Unlock()
   554  	d.aliveMembership.Remove(id)
   555  	d.deadMembership.Remove(id)
   556  	delete(d.id2Member, string(id))
   557  	delete(d.deadLastTS, string(id))
   558  	delete(d.aliveLastTS, string(id))
   559  }
   560  
   561  func (d *gossipDiscoveryImpl) isSentByMe(m *protoext.SignedGossipMessage) bool {
   562  	pkiID := m.GetAliveMsg().Membership.PkiId
   563  	if !equalPKIid(pkiID, d.self.PKIid) {
   564  		return false
   565  	}
   566  	d.logger.Debug("Got alive message about ourselves,", m)
   567  	d.lock.RLock()
   568  	diffExternalEndpoint := d.self.Endpoint != m.GetAliveMsg().Membership.Endpoint
   569  	d.lock.RUnlock()
   570  	var diffInternalEndpoint bool
   571  	secretEnvelope := m.GetSecretEnvelope()
   572  	if secretEnvelope != nil {
   573  		internalEndpoint := protoext.InternalEndpoint(secretEnvelope)
   574  		if internalEndpoint != "" {
   575  			diffInternalEndpoint = internalEndpoint != d.self.InternalEndpoint
   576  		}
   577  	}
   578  	if diffInternalEndpoint || diffExternalEndpoint {
   579  		d.logger.Error("Bad configuration detected: Received AliveMessage from a peer with the same PKI-ID as myself:", m.GossipMessage)
   580  	}
   581  	return true
   582  }
   583  
   584  func (d *gossipDiscoveryImpl) resurrectMember(am *protoext.SignedGossipMessage, t proto.PeerTime) {
   585  	d.logger.Debug("Entering, AliveMessage:", am, "t:", t)
   586  	defer d.logger.Debug("Exiting")
   587  	d.lock.Lock()
   588  	defer d.lock.Unlock()
   589  
   590  	member := am.GetAliveMsg().Membership
   591  	pkiID := member.PkiId
   592  	d.aliveLastTS[string(pkiID)] = &timestamp{
   593  		lastSeen: time.Now(),
   594  		seqNum:   t.SeqNum,
   595  		incTime:  tsToTime(t.IncNum),
   596  	}
   597  
   598  	var internalEndpoint string
   599  	if prevNetMem := d.id2Member[string(pkiID)]; prevNetMem != nil {
   600  		internalEndpoint = prevNetMem.InternalEndpoint
   601  	}
   602  	if am.Envelope.SecretEnvelope != nil {
   603  		internalEndpoint = protoext.InternalEndpoint(am.Envelope.SecretEnvelope)
   604  	}
   605  
   606  	d.id2Member[string(pkiID)] = &NetworkMember{
   607  		Endpoint:         member.Endpoint,
   608  		Metadata:         member.Metadata,
   609  		PKIid:            member.PkiId,
   610  		InternalEndpoint: internalEndpoint,
   611  	}
   612  
   613  	delete(d.deadLastTS, string(pkiID))
   614  	d.deadMembership.Remove(common.PKIidType(pkiID))
   615  	d.aliveMembership.Put(common.PKIidType(pkiID), &protoext.SignedGossipMessage{GossipMessage: am.GossipMessage, Envelope: am.Envelope})
   616  }
   617  
   618  func (d *gossipDiscoveryImpl) periodicalReconnectToDead() {
   619  	defer d.logger.Debug("Stopped")
   620  
   621  	for !d.toDie() {
   622  		wg := &sync.WaitGroup{}
   623  
   624  		for _, member := range d.copyLastSeen(d.deadLastTS) {
   625  			wg.Add(1)
   626  			go func(member NetworkMember) {
   627  				defer wg.Done()
   628  				if d.comm.Ping(&member) {
   629  					d.logger.Debug(member, "is responding, sending membership request")
   630  					d.sendMembershipRequest(&member, true)
   631  				} else {
   632  					d.logger.Debug(member, "is still dead")
   633  				}
   634  			}(member)
   635  		}
   636  
   637  		wg.Wait()
   638  		d.logger.Debug("Sleeping", d.reconnectInterval)
   639  		time.Sleep(d.reconnectInterval)
   640  	}
   641  }
   642  
   643  func (d *gossipDiscoveryImpl) sendMembershipRequest(member *NetworkMember, includeInternalEndpoint bool) {
   644  	m, err := d.createMembershipRequest(includeInternalEndpoint)
   645  	if err != nil {
   646  		d.logger.Warningf("Failed creating membership request: %+v", errors.WithStack(err))
   647  		return
   648  	}
   649  	req, err := protoext.NoopSign(m)
   650  	if err != nil {
   651  		d.logger.Errorf("Failed creating SignedGossipMessage: %+v", errors.WithStack(err))
   652  		return
   653  	}
   654  	d.comm.SendToPeer(member, req)
   655  }
   656  
   657  func (d *gossipDiscoveryImpl) createMembershipRequest(includeInternalEndpoint bool) (*proto.GossipMessage, error) {
   658  	am, err := d.createSignedAliveMessage(includeInternalEndpoint)
   659  	if err != nil {
   660  		return nil, errors.WithStack(err)
   661  	}
   662  	req := &proto.MembershipRequest{
   663  		SelfInformation: am.Envelope,
   664  		// TODO: sending the known peers is not secure because the remote peer might shouldn't know
   665  		// TODO: about the known peers. I'm deprecating this until a secure mechanism will be implemented.
   666  		// TODO: See FAB-2570 for tracking this issue.
   667  		Known: [][]byte{},
   668  	}
   669  	return &proto.GossipMessage{
   670  		Tag:   proto.GossipMessage_EMPTY,
   671  		Nonce: uint64(0),
   672  		Content: &proto.GossipMessage_MemReq{
   673  			MemReq: req,
   674  		},
   675  	}, nil
   676  }
   677  
   678  func (d *gossipDiscoveryImpl) copyLastSeen(lastSeenMap map[string]*timestamp) []NetworkMember {
   679  	d.lock.RLock()
   680  	defer d.lock.RUnlock()
   681  
   682  	res := []NetworkMember{}
   683  	for pkiIDStr := range lastSeenMap {
   684  		res = append(res, *(d.id2Member[pkiIDStr]))
   685  	}
   686  	return res
   687  }
   688  
   689  func (d *gossipDiscoveryImpl) periodicalCheckAlive() {
   690  	defer d.logger.Debug("Stopped")
   691  
   692  	for !d.toDie() {
   693  		time.Sleep(d.aliveExpirationCheckInterval)
   694  		dead := d.getDeadMembers()
   695  		if len(dead) > 0 {
   696  			d.logger.Debugf("Got %v dead members: %v", len(dead), dead)
   697  			d.expireDeadMembers(dead)
   698  		}
   699  	}
   700  }
   701  
   702  func (d *gossipDiscoveryImpl) expireDeadMembers(dead []common.PKIidType) {
   703  	d.logger.Warning("Entering", dead)
   704  	defer d.logger.Warning("Exiting")
   705  
   706  	var deadMembers2Expire []NetworkMember
   707  
   708  	d.lock.Lock()
   709  
   710  	for _, pkiID := range dead {
   711  		if _, isAlive := d.aliveLastTS[string(pkiID)]; !isAlive {
   712  			continue
   713  		}
   714  		deadMembers2Expire = append(deadMembers2Expire, d.id2Member[string(pkiID)].Clone())
   715  		// move lastTS from alive to dead
   716  		lastTS, hasLastTS := d.aliveLastTS[string(pkiID)]
   717  		if hasLastTS {
   718  			d.deadLastTS[string(pkiID)] = lastTS
   719  			delete(d.aliveLastTS, string(pkiID))
   720  		}
   721  
   722  		if am := d.aliveMembership.MsgByID(pkiID); am != nil {
   723  			d.deadMembership.Put(pkiID, am)
   724  			d.aliveMembership.Remove(pkiID)
   725  		}
   726  	}
   727  
   728  	d.lock.Unlock()
   729  
   730  	for _, member2Expire := range deadMembers2Expire {
   731  		d.logger.Warning("Closing connection to", member2Expire)
   732  		d.comm.CloseConn(&member2Expire)
   733  	}
   734  }
   735  
   736  func (d *gossipDiscoveryImpl) getDeadMembers() []common.PKIidType {
   737  	d.lock.RLock()
   738  	defer d.lock.RUnlock()
   739  
   740  	dead := []common.PKIidType{}
   741  	for id, last := range d.aliveLastTS {
   742  		elapsedNonAliveTime := time.Since(last.lastSeen)
   743  		if elapsedNonAliveTime > d.aliveExpirationTimeout {
   744  			d.logger.Warning("Haven't heard from", []byte(id), "for", elapsedNonAliveTime)
   745  			dead = append(dead, common.PKIidType(id))
   746  		}
   747  	}
   748  	return dead
   749  }
   750  
   751  func (d *gossipDiscoveryImpl) periodicalSendAlive() {
   752  	defer d.logger.Debug("Stopped")
   753  
   754  	for !d.toDie() {
   755  		d.logger.Debug("Sleeping", d.aliveTimeInterval)
   756  		time.Sleep(d.aliveTimeInterval)
   757  		msg, err := d.createSignedAliveMessage(true)
   758  		if err != nil {
   759  			d.logger.Warningf("Failed creating alive message: %+v", errors.WithStack(err))
   760  			return
   761  		}
   762  		d.lock.Lock()
   763  		d.selfAliveMessage = msg
   764  		d.lock.Unlock()
   765  		d.comm.Gossip(msg)
   766  	}
   767  }
   768  
   769  func (d *gossipDiscoveryImpl) aliveMsgAndInternalEndpoint() (*proto.GossipMessage, string) {
   770  	d.lock.Lock()
   771  	defer d.lock.Unlock()
   772  	d.seqNum++
   773  	seqNum := d.seqNum
   774  	endpoint := d.self.Endpoint
   775  	meta := d.self.Metadata
   776  	pkiID := d.self.PKIid
   777  	internalEndpoint := d.self.InternalEndpoint
   778  	msg := &proto.GossipMessage{
   779  		Tag: proto.GossipMessage_EMPTY,
   780  		Content: &proto.GossipMessage_AliveMsg{
   781  			AliveMsg: &proto.AliveMessage{
   782  				Membership: &proto.Member{
   783  					Endpoint: endpoint,
   784  					Metadata: meta,
   785  					PkiId:    pkiID,
   786  				},
   787  				Timestamp: &proto.PeerTime{
   788  					IncNum: uint64(d.incTime),
   789  					SeqNum: seqNum,
   790  				},
   791  			},
   792  		},
   793  	}
   794  	return msg, internalEndpoint
   795  }
   796  
   797  func (d *gossipDiscoveryImpl) createSignedAliveMessage(includeInternalEndpoint bool) (*protoext.SignedGossipMessage, error) {
   798  	msg, internalEndpoint := d.aliveMsgAndInternalEndpoint()
   799  	envp := d.crypt.SignMessage(msg, internalEndpoint)
   800  	if envp == nil {
   801  		return nil, errors.New("Failed signing message")
   802  	}
   803  	signedMsg := &protoext.SignedGossipMessage{
   804  		GossipMessage: msg,
   805  		Envelope:      envp,
   806  	}
   807  
   808  	if !includeInternalEndpoint {
   809  		signedMsg.Envelope.SecretEnvelope = nil
   810  	}
   811  
   812  	return signedMsg, nil
   813  }
   814  
   815  func (d *gossipDiscoveryImpl) learnExistingMembers(aliveArr []*protoext.SignedGossipMessage) {
   816  	d.logger.Debugf("Entering: learnedMembers={%v}", aliveArr)
   817  	defer d.logger.Debug("Exiting")
   818  
   819  	d.lock.Lock()
   820  	defer d.lock.Unlock()
   821  
   822  	for _, m := range aliveArr {
   823  		am := m.GetAliveMsg()
   824  		if am == nil {
   825  			d.logger.Warning("Expected alive message, got instead:", m)
   826  			return
   827  		}
   828  		d.logger.Debug("updating", protoext.AliveMessageToString(am))
   829  
   830  		var internalEndpoint string
   831  		if prevNetMem := d.id2Member[string(am.Membership.PkiId)]; prevNetMem != nil {
   832  			internalEndpoint = prevNetMem.InternalEndpoint
   833  		}
   834  		if m.Envelope.SecretEnvelope != nil {
   835  			internalEndpoint = protoext.InternalEndpoint(m.Envelope.SecretEnvelope)
   836  		}
   837  
   838  		// update member's data
   839  		member := d.id2Member[string(am.Membership.PkiId)]
   840  		member.Endpoint = am.Membership.Endpoint
   841  		member.Metadata = am.Membership.Metadata
   842  		member.InternalEndpoint = internalEndpoint
   843  
   844  		if _, isKnownAsDead := d.deadLastTS[string(am.Membership.PkiId)]; isKnownAsDead {
   845  			d.logger.Warning(am.Membership, "has already expired")
   846  			continue
   847  		}
   848  
   849  		if _, isKnownAsAlive := d.aliveLastTS[string(am.Membership.PkiId)]; !isKnownAsAlive {
   850  			d.logger.Warning(am.Membership, "has already expired")
   851  			continue
   852  		} else {
   853  			d.logger.Debug("Updating aliveness data:", protoext.AliveMessageToString(am))
   854  			// update existing aliveness data
   855  			alive := d.aliveLastTS[string(am.Membership.PkiId)]
   856  			alive.incTime = tsToTime(am.Timestamp.IncNum)
   857  			alive.lastSeen = time.Now()
   858  			alive.seqNum = am.Timestamp.SeqNum
   859  
   860  			if am := d.aliveMembership.MsgByID(m.GetAliveMsg().Membership.PkiId); am == nil {
   861  				d.logger.Debug("Adding", am, "to aliveMembership")
   862  				msg := &protoext.SignedGossipMessage{GossipMessage: m.GossipMessage, Envelope: am.Envelope}
   863  				d.aliveMembership.Put(m.GetAliveMsg().Membership.PkiId, msg)
   864  			} else {
   865  				d.logger.Debug("Replacing", am, "in aliveMembership")
   866  				am.GossipMessage = m.GossipMessage
   867  				am.Envelope = m.Envelope
   868  			}
   869  		}
   870  	}
   871  }
   872  
   873  func (d *gossipDiscoveryImpl) learnNewMembers(aliveMembers []*protoext.SignedGossipMessage, deadMembers []*protoext.SignedGossipMessage) {
   874  	d.logger.Debugf("Entering: learnedMembers={%v}, deadMembers={%v}", aliveMembers, deadMembers)
   875  	defer d.logger.Debugf("Exiting")
   876  
   877  	d.lock.Lock()
   878  	defer d.lock.Unlock()
   879  
   880  	for _, am := range aliveMembers {
   881  		if equalPKIid(am.GetAliveMsg().Membership.PkiId, d.self.PKIid) {
   882  			continue
   883  		}
   884  		d.aliveLastTS[string(am.GetAliveMsg().Membership.PkiId)] = &timestamp{
   885  			incTime:  tsToTime(am.GetAliveMsg().Timestamp.IncNum),
   886  			lastSeen: time.Now(),
   887  			seqNum:   am.GetAliveMsg().Timestamp.SeqNum,
   888  		}
   889  
   890  		d.aliveMembership.Put(am.GetAliveMsg().Membership.PkiId, &protoext.SignedGossipMessage{GossipMessage: am.GossipMessage, Envelope: am.Envelope})
   891  		d.logger.Debugf("Learned about a new alive member: %v", am)
   892  	}
   893  
   894  	for _, dm := range deadMembers {
   895  		if equalPKIid(dm.GetAliveMsg().Membership.PkiId, d.self.PKIid) {
   896  			continue
   897  		}
   898  		d.deadLastTS[string(dm.GetAliveMsg().Membership.PkiId)] = &timestamp{
   899  			incTime:  tsToTime(dm.GetAliveMsg().Timestamp.IncNum),
   900  			lastSeen: time.Now(),
   901  			seqNum:   dm.GetAliveMsg().Timestamp.SeqNum,
   902  		}
   903  
   904  		d.deadMembership.Put(dm.GetAliveMsg().Membership.PkiId, &protoext.SignedGossipMessage{GossipMessage: dm.GossipMessage, Envelope: dm.Envelope})
   905  		d.logger.Debugf("Learned about a new dead member: %v", dm)
   906  	}
   907  
   908  	// update the member in any case
   909  	for _, a := range [][]*protoext.SignedGossipMessage{aliveMembers, deadMembers} {
   910  		for _, m := range a {
   911  			member := m.GetAliveMsg()
   912  			if member == nil {
   913  				d.logger.Warning("Expected alive message, got instead:", m)
   914  				return
   915  			}
   916  
   917  			var internalEndpoint string
   918  			if m.Envelope.SecretEnvelope != nil {
   919  				internalEndpoint = protoext.InternalEndpoint(m.Envelope.SecretEnvelope)
   920  			}
   921  
   922  			if prevNetMem := d.id2Member[string(member.Membership.PkiId)]; prevNetMem != nil {
   923  				internalEndpoint = prevNetMem.InternalEndpoint
   924  			}
   925  
   926  			d.id2Member[string(member.Membership.PkiId)] = &NetworkMember{
   927  				Endpoint:         member.Membership.Endpoint,
   928  				Metadata:         member.Membership.Metadata,
   929  				PKIid:            member.Membership.PkiId,
   930  				InternalEndpoint: internalEndpoint,
   931  			}
   932  		}
   933  	}
   934  }
   935  
   936  func (d *gossipDiscoveryImpl) GetMembership() []NetworkMember {
   937  	if d.toDie() {
   938  		return []NetworkMember{}
   939  	}
   940  	d.lock.RLock()
   941  	defer d.lock.RUnlock()
   942  
   943  	response := []NetworkMember{}
   944  	for _, m := range d.aliveMembership.ToSlice() {
   945  		member := m.GetAliveMsg()
   946  		response = append(response, NetworkMember{
   947  			PKIid:            member.Membership.PkiId,
   948  			Endpoint:         member.Membership.Endpoint,
   949  			Metadata:         member.Membership.Metadata,
   950  			InternalEndpoint: d.id2Member[string(m.GetAliveMsg().Membership.PkiId)].InternalEndpoint,
   951  			Envelope:         m.Envelope,
   952  		})
   953  	}
   954  	return response
   955  
   956  }
   957  
   958  func tsToTime(ts uint64) time.Time {
   959  	return time.Unix(int64(0), int64(ts))
   960  }
   961  
   962  func (d *gossipDiscoveryImpl) UpdateMetadata(md []byte) {
   963  	d.lock.Lock()
   964  	defer d.lock.Unlock()
   965  	d.self.Metadata = md
   966  }
   967  
   968  func (d *gossipDiscoveryImpl) UpdateEndpoint(endpoint string) {
   969  	d.lock.Lock()
   970  	defer d.lock.Unlock()
   971  
   972  	d.self.Endpoint = endpoint
   973  }
   974  
   975  func (d *gossipDiscoveryImpl) Self() NetworkMember {
   976  	var env *proto.Envelope
   977  	msg, _ := d.aliveMsgAndInternalEndpoint()
   978  	sMsg, err := protoext.NoopSign(msg)
   979  	if err != nil {
   980  		d.logger.Warning("Failed creating SignedGossipMessage:", err)
   981  	} else {
   982  		env = sMsg.Envelope
   983  	}
   984  	mem := msg.GetAliveMsg().Membership
   985  	return NetworkMember{
   986  		Endpoint: mem.Endpoint,
   987  		Metadata: mem.Metadata,
   988  		PKIid:    mem.PkiId,
   989  		Envelope: env,
   990  	}
   991  }
   992  
   993  func (d *gossipDiscoveryImpl) toDie() bool {
   994  	select {
   995  	case <-d.toDieChan:
   996  		return true
   997  	default:
   998  		return false
   999  	}
  1000  }
  1001  
  1002  func (d *gossipDiscoveryImpl) Stop() {
  1003  	select {
  1004  	case <-d.toDieChan:
  1005  	default:
  1006  		close(d.toDieChan)
  1007  		defer d.logger.Info("Stopped")
  1008  		d.logger.Info("Stopping")
  1009  		d.msgStore.Stop()
  1010  	}
  1011  }
  1012  
  1013  func copyNetworkMember(member *NetworkMember) *NetworkMember {
  1014  	if member == nil {
  1015  		return nil
  1016  	} else {
  1017  		copiedNetworkMember := &NetworkMember{}
  1018  		*copiedNetworkMember = *member
  1019  		return copiedNetworkMember
  1020  	}
  1021  }
  1022  
  1023  func equalPKIid(a, b common.PKIidType) bool {
  1024  	return bytes.Equal(a, b)
  1025  }
  1026  
  1027  func same(a *timestamp, b *proto.PeerTime) bool {
  1028  	return uint64(a.incTime.UnixNano()) == b.IncNum && a.seqNum == b.SeqNum
  1029  }
  1030  
  1031  func before(a *timestamp, b *proto.PeerTime) bool {
  1032  	return (uint64(a.incTime.UnixNano()) == b.IncNum && a.seqNum < b.SeqNum) ||
  1033  		uint64(a.incTime.UnixNano()) < b.IncNum
  1034  }
  1035  
  1036  type aliveMsgStore struct {
  1037  	msgstore.MessageStore
  1038  }
  1039  
  1040  func newAliveMsgStore(d *gossipDiscoveryImpl) *aliveMsgStore {
  1041  	policy := protoext.NewGossipMessageComparator(0)
  1042  	trigger := func(m interface{}) {}
  1043  	aliveMsgTTL := d.aliveExpirationTimeout * msgExpirationFactor
  1044  	externalLock := func() { d.lock.Lock() }
  1045  	externalUnlock := func() { d.lock.Unlock() }
  1046  	callback := func(m interface{}) {
  1047  		msg := m.(*protoext.SignedGossipMessage)
  1048  		if !protoext.IsAliveMsg(msg.GossipMessage) {
  1049  			return
  1050  		}
  1051  		membership := msg.GetAliveMsg().Membership
  1052  		id := membership.PkiId
  1053  		endpoint := membership.Endpoint
  1054  		internalEndpoint := protoext.InternalEndpoint(msg.SecretEnvelope)
  1055  		if util.Contains(endpoint, d.bootstrapPeers) || util.Contains(internalEndpoint, d.bootstrapPeers) {
  1056  			// Never remove a bootstrap peer
  1057  			return
  1058  		}
  1059  		d.logger.Infof("Removing member: Endpoint: %s, InternalEndpoint: %s, PKIID: %x", endpoint, internalEndpoint, id)
  1060  		d.aliveMembership.Remove(id)
  1061  		d.deadMembership.Remove(id)
  1062  		delete(d.id2Member, string(id))
  1063  		delete(d.deadLastTS, string(id))
  1064  		delete(d.aliveLastTS, string(id))
  1065  	}
  1066  
  1067  	s := &aliveMsgStore{
  1068  		MessageStore: msgstore.NewMessageStoreExpirable(policy, trigger, aliveMsgTTL, externalLock, externalUnlock, callback),
  1069  	}
  1070  	return s
  1071  }
  1072  
  1073  func (s *aliveMsgStore) Add(msg interface{}) bool {
  1074  	m := msg.(*protoext.SignedGossipMessage)
  1075  	if !protoext.IsAliveMsg(m.GossipMessage) {
  1076  		panic(fmt.Sprint("Msg ", msg, " is not AliveMsg"))
  1077  	}
  1078  	return s.MessageStore.Add(msg)
  1079  }
  1080  
  1081  func (s *aliveMsgStore) CheckValid(msg interface{}) bool {
  1082  	m := msg.(*protoext.SignedGossipMessage)
  1083  	if !protoext.IsAliveMsg(m.GossipMessage) {
  1084  		panic(fmt.Sprint("Msg ", msg, " is not AliveMsg"))
  1085  	}
  1086  	return s.MessageStore.CheckValid(msg)
  1087  }