Skip to content

Commit b7b5c4e

Browse files
committed
[FAB-2198] Gossip envelope refactoring
In the previous episode of [FAB-2198]: https://gerrit.hyperledger.org/r/#/c/5907/ Adjust gossip membership layer We adjusted the discovery layer and got rid of the usage of the protos there. Now, I'm gradually integrating the envelope with the gossip message and actually making the signing and verification work on the raw payload instead of on a computed payload that is non deterministic. Also, the SignedEndpoint which was a part of the membership entity "Member" is no more, and its functionality was moved outside of the GossipMessage, to an external "Secret" message type. This type will be used to hold parts of GossipMessage that the peers may want to omit as they forward messages to peers that shouldn't get this information. The current use-case for this, is FAB-2007 that enforces peers to not expose the internal endpoints of peers in their own organization. This data can't reside inside the GossipMessage anymore, because it is marshalled into a payload and signed. Therefore, we need to extract it into a side entity that will be part of the Envelope that will be sent in gossip. T hen, the peers can easily omit this envelope while preserving the signature on the payload that the source peer produced. In the (very-soon) future, I'll get rid of the coupling between the GossipMessage and the Envelope reference inside of it. Change-Id: Ib910cba1f69bd356174ceb64ee22e2a1d9d15cf5 Signed-off-by: Yacov Manevich <[email protected]>
1 parent ea7015e commit b7b5c4e

19 files changed

+610
-398
lines changed

gossip/comm/comm_impl.go

+27-16
Original file line numberDiff line numberDiff line change
@@ -407,11 +407,12 @@ func (c *commImpl) authenticateRemotePeer(stream stream) (common.PKIidType, erro
407407
cMsg = c.createConnectionMsg(c.PKIID, c.selfCertHash, c.peerIdentity, signer)
408408

409409
c.logger.Debug("Sending", cMsg, "to", remoteAddress)
410-
stream.Send(cMsg)
411-
m := readWithTimeout(stream, util.GetDurationOrDefault("peer.gossip.connTimeout", defConnTimeout))
412-
if m == nil {
413-
c.logger.Warning("Timed out waiting for connection message from", remoteAddress)
414-
return nil, errors.New("Timed out")
410+
stream.Send(cMsg.Envelope)
411+
m, err := readWithTimeout(stream, util.GetDurationOrDefault("peer.gossip.connTimeout", defConnTimeout), remoteAddress)
412+
if err != nil {
413+
err := fmt.Errorf("Failed reading messge from %s, reason: %v", remoteAddress, err)
414+
c.logger.Warning(err)
415+
return nil, err
415416
}
416417
receivedMsg := m.GetConn()
417418
if receivedMsg == nil {
@@ -505,25 +506,38 @@ func (c *commImpl) disconnect(pkiID common.PKIidType) {
505506
c.connStore.closeByPKIid(pkiID)
506507
}
507508

508-
func readWithTimeout(stream interface{}, timeout time.Duration) *proto.GossipMessage {
509+
func readWithTimeout(stream interface{}, timeout time.Duration, address string) (*proto.GossipMessage, error) {
509510
incChan := make(chan *proto.GossipMessage, 1)
511+
errChan := make(chan error, 1)
510512
go func() {
511513
if srvStr, isServerStr := stream.(proto.Gossip_GossipStreamServer); isServerStr {
512514
if m, err := srvStr.Recv(); err == nil {
513-
incChan <- m
515+
msg, err := m.ToGossipMessage()
516+
if err != nil {
517+
errChan <- err
518+
return
519+
}
520+
incChan <- msg
514521
}
515522
}
516523
if clStr, isClientStr := stream.(proto.Gossip_GossipStreamClient); isClientStr {
517524
if m, err := clStr.Recv(); err == nil {
518-
incChan <- m
525+
msg, err := m.ToGossipMessage()
526+
if err != nil {
527+
errChan <- err
528+
return
529+
}
530+
incChan <- msg
519531
}
520532
}
521533
}()
522534
select {
523535
case <-time.NewTicker(timeout).C:
524-
return nil
536+
return nil, fmt.Errorf("Timed out waiting for connection message from %s", address)
525537
case m := <-incChan:
526-
return m
538+
return m, nil
539+
case err := <-errChan:
540+
return nil, err
527541
}
528542
}
529543

@@ -539,16 +553,13 @@ func (c *commImpl) createConnectionMsg(pkiID common.PKIidType, hash []byte, cert
539553
},
540554
},
541555
}
542-
if err := m.Sign(signer); err != nil {
543-
c.logger.Panicf("Gossip failed to sign a message using the peer identity.\n Halting execution.\nActual error: %v", err)
544-
}
545-
556+
m.Sign(signer)
546557
return m
547558
}
548559

549560
type stream interface {
550-
Send(*proto.GossipMessage) error
551-
Recv() (*proto.GossipMessage, error)
561+
Send(envelope *proto.Envelope) error
562+
Recv() (*proto.Envelope, error)
552563
grpc.Stream
553564
}
554565

gossip/comm/comm_test.go

+10-12
Original file line numberDiff line numberDiff line change
@@ -130,24 +130,26 @@ func handshaker(endpoint string, comm Comm, t *testing.T, sigMutator func([]byte
130130
})
131131

132132
if sigMutator != nil {
133-
msg.Signature = sigMutator(msg.Signature)
133+
msg.Envelope.Signature = sigMutator(msg.Envelope.Signature)
134134
}
135135

136-
stream.Send(msg)
137-
msg, err = stream.Recv()
136+
stream.Send(msg.Envelope)
137+
envelope, err := stream.Recv()
138+
assert.NoError(t, err, "%v", err)
139+
msg, err = envelope.ToGossipMessage()
138140
assert.NoError(t, err, "%v", err)
139141
if sigMutator == nil {
140142
hash := extractCertificateHashFromContext(stream.Context())
141143
expectedMsg := c.createConnectionMsg(common.PKIidType("localhost:9611"), hash, []byte("localhost:9611"), func(msg []byte) ([]byte, error) {
142144
return msg, nil
143145
})
144-
assert.Equal(t, expectedMsg.Signature, msg.Signature)
146+
assert.Equal(t, expectedMsg.Envelope.Signature, msg.Envelope.Signature)
145147
}
146148
assert.Equal(t, []byte("localhost:9611"), msg.GetConn().PkiID)
147149
msg2Send := createGossipMsg()
148150
nonce := uint64(rand.Int())
149151
msg2Send.Nonce = nonce
150-
go stream.Send(msg2Send)
152+
go stream.Send(msg2Send.NoopSign())
151153
return acceptChan
152154
}
153155

@@ -347,17 +349,13 @@ func TestResponses(t *testing.T) {
347349
defer comm1.Stop()
348350
defer comm2.Stop()
349351

350-
nonceIncrememter := func(msg proto.ReceivedMessage) proto.ReceivedMessage {
351-
msg.GetGossipMessage().Nonce++
352-
return msg
353-
}
354-
355352
msg := createGossipMsg()
356353
go func() {
357354
inChan := comm1.Accept(acceptAll)
358355
for m := range inChan {
359-
m = nonceIncrememter(m)
360-
m.Respond(m.GetGossipMessage())
356+
reply := createGossipMsg()
357+
reply.Nonce = m.GetGossipMessage().Nonce + 1
358+
m.Respond(reply)
361359
}
362360
}()
363361
expectedNOnce := uint64(msg.Nonce + 1)

gossip/comm/conn.go

+15-6
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,13 @@ func (conn *connection) send(msg *proto.GossipMessage, onErr func(error)) {
248248
return
249249
}
250250

251+
if msg.Envelope == nil {
252+
msg.NoopSign()
253+
}
254+
251255
m := &msgSending{
252-
msg: msg,
253-
onErr: onErr,
256+
envelope: msg.Envelope,
257+
onErr: onErr,
254258
}
255259

256260
conn.outBuff <- m
@@ -294,7 +298,7 @@ func (conn *connection) writeToStream() {
294298
}
295299
select {
296300
case m := <-conn.outBuff:
297-
err := stream.Send(m.msg)
301+
err := stream.Send(m.envelope)
298302
if err != nil {
299303
go m.onErr(err)
300304
return
@@ -319,7 +323,7 @@ func (conn *connection) readFromStream(errChan chan error, msgChan chan *proto.G
319323
errChan <- errors.New("Stream is nil")
320324
return
321325
}
322-
msg, err := stream.Recv()
326+
envelope, err := stream.Recv()
323327
if conn.toDie() {
324328
conn.logger.Debug(conn.pkiID, "canceling read because closing")
325329
return
@@ -329,6 +333,11 @@ func (conn *connection) readFromStream(errChan chan error, msgChan chan *proto.G
329333
conn.logger.Debug(conn.pkiID, "Got error, aborting:", err)
330334
return
331335
}
336+
msg, err := envelope.ToGossipMessage()
337+
if err != nil {
338+
errChan <- err
339+
conn.logger.Warning(conn.pkiID, "Got error, aborting:", err)
340+
}
332341
msgChan <- msg
333342
}
334343
}
@@ -354,6 +363,6 @@ func (conn *connection) getStream() stream {
354363
}
355364

356365
type msgSending struct {
357-
msg *proto.GossipMessage
358-
onErr func(error)
366+
envelope *proto.Envelope
367+
onErr func(error)
359368
}

gossip/comm/mock/mock_comm.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,9 @@ func (packet *packetMock) Respond(msg *proto.GossipMessage) {
9191
}
9292
}
9393

94-
// GetSourceMessage Returns the SignedGossipMessage the ReceivedMessage was
94+
// GetSourceEnvelope Returns the Envelope the ReceivedMessage was
9595
// constructed with
96-
func (packet *packetMock) GetSourceMessage() *proto.SignedGossipMessage {
96+
func (packet *packetMock) GetSourceEnvelope() *proto.Envelope {
9797
return nil
9898
}
9999

gossip/comm/msg.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ type ReceivedMessageImpl struct {
3030
conn *connection
3131
}
3232

33-
// GetSourceMessage Returns the SignedGossipMessage the ReceivedMessage was
33+
// GetSourceEnvelope Returns the Envelope the ReceivedMessage was
3434
// constructed with
35-
func (m *ReceivedMessageImpl) GetSourceMessage() *proto.SignedGossipMessage {
36-
return nil
35+
func (m *ReceivedMessageImpl) GetSourceEnvelope() *proto.Envelope {
36+
return m.Envelope
3737
}
3838

3939
// Respond sends a msg to the source that sent the ReceivedMessageImpl

gossip/discovery/discovery.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ type CryptoService interface {
2727
ValidateAliveMsg(*proto.GossipMessage) bool
2828

2929
// SignMessage signs a message
30-
SignMessage(m *proto.GossipMessage) *proto.GossipMessage
30+
SignMessage(m *proto.GossipMessage, internalEndpoint string) *proto.Envelope
3131
}
3232

3333
// CommService is an interface that the discovery expects to be implemented and passed on creation
@@ -57,15 +57,15 @@ type NetworkMember struct {
5757
Endpoint string
5858
Metadata []byte
5959
PKIid common.PKIidType
60-
InternalEndpoint *proto.SignedEndpoint
60+
InternalEndpoint string
6161
}
6262

6363
// PreferredEndpoint computes the endpoint to connect to,
6464
// while preferring internal endpoint over the standard
6565
// endpoint
6666
func (nm NetworkMember) PreferredEndpoint() string {
67-
if nm.InternalEndpoint != nil && nm.InternalEndpoint.Endpoint != "" {
68-
return nm.InternalEndpoint.Endpoint
67+
if nm.InternalEndpoint != "" {
68+
return nm.InternalEndpoint
6969
}
7070
return nm.Endpoint
7171
}

0 commit comments

Comments
 (0)