func (g *gossipServiceImpl) createCertStorePuller() pull.Mediator { conf := pull.PullConfig{ MsgType: proto.PullMsgType_IdentityMsg, Channel: []byte(""), Id: g.conf.SelfEndpoint, PeerCountToSelect: g.conf.PullPeerNum, PullInterval: g.conf.PullInterval, Tag: proto.GossipMessage_EMPTY, } pkiIDFromMsg := func(msg *proto.GossipMessage) string { identityMsg := msg.GetPeerIdentity() if identityMsg == nil || identityMsg.PkiID == nil { return "" } return fmt.Sprintf("%s", string(identityMsg.PkiID)) } certConsumer := func(msg *proto.GossipMessage) { idMsg := msg.GetPeerIdentity() if idMsg == nil || idMsg.Cert == nil || idMsg.PkiID == nil { g.logger.Warning("Invalid PeerIdentity:", idMsg) return } err := g.idMapper.Put(common.PKIidType(idMsg.PkiID), api.PeerIdentityType(idMsg.Cert)) if err != nil { g.logger.Warning("Failed associating PKI-ID with certificate:", err) } } return pull.NewPullMediator(conf, g.comm, g.disc, pkiIDFromMsg, certConsumer) }
func TestMockComm(t *testing.T) { first := &socketMock{"first", make(chan interface{})} second := &socketMock{"second", make(chan interface{})} members := make(map[string]*socketMock) members[first.endpoint] = first members[second.endpoint] = second comm1 := NewCommMock(first.endpoint, members) defer comm1.Stop() msgCh := comm1.Accept(func(message interface{}) bool { return message.(comm.ReceivedMessage).GetGossipMessage().GetStateRequest() != nil || message.(comm.ReceivedMessage).GetGossipMessage().GetStateResponse() != nil }) comm2 := NewCommMock(second.endpoint, members) defer comm2.Stop() comm2.Send(&proto.GossipMessage{ Content: &proto.GossipMessage_StateRequest{&proto.RemoteStateRequest{ SeqNums: []uint64{1, 2, 3}, }}, }, &comm.RemotePeer{"first", common.PKIidType("first")}) msg := <-msgCh assert.NotNil(t, msg.GetGossipMessage().GetStateRequest()) }
func (d *gossipDiscoveryImpl) getKnownPeers() [][]byte { d.lock.RLock() defer d.lock.RUnlock() peers := [][]byte{} for id := range d.id2Member { peers = append(peers, common.PKIidType(id)) } return peers }
func (d *gossipDiscoveryImpl) getDeadMembers() []common.PKIidType { d.lock.RLock() defer d.lock.RUnlock() dead := []common.PKIidType{} for id, last := range d.aliveLastTS { elapsedNonAliveTime := time.Since(last.lastSeen) if elapsedNonAliveTime.Nanoseconds() > aliveExpirationTimeout.Nanoseconds() { d.logger.Warning("Haven't heard from", id, "for", elapsedNonAliveTime) dead = append(dead, common.PKIidType(id)) } } return dead }
func TestMockComm_PingPong(t *testing.T) { members := make(map[string]*socketMock) members["peerA"] = &socketMock{"peerA", make(chan interface{})} members["peerB"] = &socketMock{"peerB", make(chan interface{})} peerA := NewCommMock("peerA", members) peerB := NewCommMock("peerB", members) all := func(interface{}) bool { return true } rcvChA := peerA.Accept(all) rcvChB := peerB.Accept(all) peerA.Send(&proto.GossipMessage{ Content: &proto.GossipMessage_DataMsg{ &proto.DataMessage{ &proto.Payload{1, "", []byte("Ping")}, }}, }, &comm.RemotePeer{"peerB", common.PKIidType("peerB")}) msg := <-rcvChB dataMsg := msg.GetGossipMessage().GetDataMsg() data := string(dataMsg.Payload.Data) assert.Equal(t, "Ping", data) msg.Respond(&proto.GossipMessage{ Content: &proto.GossipMessage_DataMsg{ &proto.DataMessage{ &proto.Payload{1, "", []byte("Pong")}, }}, }) msg = <-rcvChA dataMsg = msg.GetGossipMessage().GetDataMsg() data = string(dataMsg.Payload.Data) assert.Equal(t, "Pong", data) }
func newCertStore(puller pull.Mediator, idMapper identity.Mapper, selfIdentity api.PeerIdentityType, mcs api.MessageCryptoService) *certStore { selfPKIID := idMapper.GetPKIidOfCert(selfIdentity) logger := util.GetLogger("certStore", string(selfPKIID)) if err := idMapper.Put(selfPKIID, selfIdentity); err != nil { logger.Error("Failed associating self PKIID to cert:", err) panic(fmt.Errorf("Failed associating self PKIID to cert: %v", err)) } certStore := &certStore{ mcs: mcs, pull: puller, idMapper: idMapper, selfIdentity: selfIdentity, logger: logger, } certStore.logger = util.GetLogger("certStore", string(selfPKIID)) if err := certStore.idMapper.Put(selfPKIID, selfIdentity); err != nil { certStore.logger.Panic("Failed associating self PKIID to cert:", err) } puller.Add(certStore.createIdentityMessage()) puller.RegisterMsgHook(pull.ResponseMsgType, func(_ []string, msgs []*proto.GossipMessage, _ comm.ReceivedMessage) { for _, msg := range msgs { pkiID := common.PKIidType(msg.GetPeerIdentity().PkiID) cert := api.PeerIdentityType(msg.GetPeerIdentity().Cert) if err := certStore.idMapper.Put(pkiID, cert); err != nil { certStore.logger.Warning("Failed adding identity", cert, ", reason:", err) } } }) puller.Add(certStore.createIdentityMessage()) return certStore }
func (g *gossipServiceImpl) validateIdentityMsg(msg *proto.GossipMessage) error { if msg.GetPeerIdentity() == nil { return fmt.Errorf("Identity empty") } idMsg := msg.GetPeerIdentity() pkiID := idMsg.PkiID cert := idMsg.Cert sig := idMsg.Sig if bytes.Equal(g.idMapper.GetPKIidOfCert(api.PeerIdentityType(cert)), common.PKIidType(pkiID)) { return fmt.Errorf("Calculated pkiID doesn't match identity") } idMsg.Sig = nil b, err := prot.Marshal(idMsg) if err != nil { return fmt.Errorf("Failed marshalling: %v", err) } err = g.mcs.Verify(api.PeerIdentityType(cert), sig, b) if err != nil { return fmt.Errorf("Failed verifying message: %v", err) } idMsg.Sig = sig return nil }
// GetPKIid returns this instance's PKI id func (mock *commMock) GetPKIid() common.PKIidType { return common.PKIidType(mock.id) }
// GetPKIidOfCert returns the PKI-ID of a peer's identity func (*naiveCryptoService) GetPKIidOfCert(peerIdentity api.PeerIdentityType) common.PKIidType { return common.PKIidType(peerIdentity) }
func (g *gossipServiceImpl) handleMessage(m comm.ReceivedMessage) { if g.toDie() { return } g.logger.Info("Entering,", m) defer g.logger.Info("Exiting") if m == nil || m.GetGossipMessage() == nil { return } msg := m.GetGossipMessage() if msg.IsAliveMsg() || msg.IsDataMsg() { if msg.IsAliveMsg() { if !g.disSecAdap.ValidateAliveMsg(msg.GetAliveMsg()) { g.logger.Warning("AliveMessage", m.GetGossipMessage(), "isn't authentic. Discarding it") return } am := msg.GetAliveMsg() storedIdentity, _ := g.idMapper.Get(common.PKIidType(am.Membership.PkiID)) // If peer's certificate is included inside AliveMessage, and we don't have a mapping between // its PKI-ID and certificate, create a mapping for it now. if identity := am.Identity; identity != nil && storedIdentity == nil { err := g.idMapper.Put(common.PKIidType(am.Membership.PkiID), api.PeerIdentityType(identity)) if err != nil { g.logger.Warning("Failed adding identity of", am, "into identity store:", err) return } g.logger.Info("Learned identity of", am.Membership.PkiID) } } if msg.IsDataMsg() { blockMsg := msg.GetDataMsg() if blockMsg.Payload == nil { g.logger.Warning("Empty block! Discarding it") return } if err := g.mcs.VerifyBlock(blockMsg); err != nil { g.logger.Warning("Could not verify block", blockMsg.Payload.SeqNum, "Discarding it") return } } added := g.msgStore.add(msg) if added { g.emitter.Add(msg) if dataMsg := m.GetGossipMessage().GetDataMsg(); dataMsg != nil { g.blocksPuller.Add(msg) g.DeMultiplex(msg) } } } if selectOnlyDiscoveryMessages(m) { g.forwardDiscoveryMsg(m) } if msg.IsPullMsg() { switch msgType := msg.GetPullMsgType(); msgType { case proto.PullMsgType_BlockMessage: g.blocksPuller.HandleMessage(m) case proto.PullMsgType_IdentityMsg: g.certStore.handleMessage(m) default: g.logger.Warning("Got invalid pull message type:", msgType) } } }