From 8d2a27af7d1d23119da66585d71f7b1e60fde3d3 Mon Sep 17 00:00:00 2001 From: Steve Simpson Date: Thu, 8 Jul 2021 15:51:22 +0200 Subject: [PATCH] Fix for compound messages containing >255 messages. --- memberlist_test.go | 6 +++--- state.go | 10 ++++++---- util.go | 17 +++++++++++++++++ 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/memberlist_test.go b/memberlist_test.go index 70b5d780c..6a1eb70a0 100644 --- a/memberlist_test.go +++ b/memberlist_test.go @@ -1200,9 +1200,9 @@ func TestMemberlist_UserData(t *testing.T) { bindPort := m1.config.BindPort - bcasts := [][]byte{ - []byte("test"), - []byte("foobar"), + bcasts := make([][]byte, 256) + for i := range bcasts { + bcasts[i] = []byte(fmt.Sprintf("%d", i)) } // Create a second node diff --git a/state.go b/state.go index 5e4f7fdd7..95e6ddc48 100644 --- a/state.go +++ b/state.go @@ -606,10 +606,12 @@ func (m *Memberlist) gossip() { m.logger.Printf("[ERR] memberlist: Failed to send gossip to %s: %s", addr, err) } } else { - // Otherwise create and send a compound message - compound := makeCompoundMessage(msgs) - if err := m.rawSendMsgPacket(node.FullAddress(), &node, compound.Bytes()); err != nil { - m.logger.Printf("[ERR] memberlist: Failed to send gossip to %s: %s", addr, err) + // Otherwise create and send one or more compound messages + compounds := makeCompoundMessages(msgs) + for _, compound := range compounds { + if err := m.rawSendMsgPacket(node.FullAddress(), &node, compound.Bytes()); err != nil { + m.logger.Printf("[ERR] memberlist: Failed to send gossip to %s: %s", addr, err) + } } } } diff --git a/util.go b/util.go index 16a7d36d0..96d2c6b8f 100644 --- a/util.go +++ b/util.go @@ -152,6 +152,23 @@ OUTER: return kNodes } +// makeCompoundMessages takes a list of messages and packs +// them into one or multiple messages based on the limitations +// of compound messages (255 messages each). +func makeCompoundMessages(msgs [][]byte) []*bytes.Buffer { + const maxMsgs = 255 + bufs := make([]*bytes.Buffer, 0, (len(msgs)+(maxMsgs-1))/maxMsgs) + + for ; len(msgs) > maxMsgs; msgs = msgs[maxMsgs:] { + bufs = append(bufs, makeCompoundMessage(msgs[:maxMsgs])) + } + if len(msgs) > 0 { + bufs = append(bufs, makeCompoundMessage(msgs)) + } + + return bufs +} + // makeCompoundMessage takes a list of messages and generates // a single compound message containing all of them func makeCompoundMessage(msgs [][]byte) *bytes.Buffer {