diff --git a/router/gossip.go b/router/gossip.go index d4293a4d..f66ea9d0 100644 --- a/router/gossip.go +++ b/router/gossip.go @@ -101,11 +101,22 @@ func (router *Router) NewGossip(channelName string, g Gossiper) Gossip { return channel } -func (router *Router) gossipChannel(channelName string) (*GossipChannel, bool) { +func (router *Router) gossipChannel(channelName string) *GossipChannel { router.gossipLock.RLock() - defer router.gossipLock.RUnlock() channel, found := router.gossipChannels[channelName] - return channel, found + router.gossipLock.RUnlock() + if found { + return channel + } + router.gossipLock.Lock() + defer router.gossipLock.Unlock() + if channel, found = router.gossipChannels[channelName]; found { + return channel + } + channel = NewGossipChannel(channelName, router.Ourself, router.Routes, &surrogateGossiper) + channel.log("created surrogate channel") + router.gossipChannels[channelName] = channel + return channel } func (router *Router) gossipChannelSet() map[*GossipChannel]struct{} { diff --git a/router/gossip_channel.go b/router/gossip_channel.go index 0b1e808c..da7dc0ec 100644 --- a/router/gossip_channel.go +++ b/router/gossip_channel.go @@ -3,7 +3,6 @@ package router import ( "bytes" "encoding/gob" - "fmt" "log" "sync" ) @@ -37,10 +36,7 @@ func (router *Router) handleGossip(tag ProtocolTag, payload []byte) error { if err := decoder.Decode(&channelName); err != nil { return err } - channel, found := router.gossipChannel(channelName) - if !found { - return fmt.Errorf("[gossip] received unknown channel with name %s", channelName) - } + channel := router.gossipChannel(channelName) var srcName PeerName if err := decoder.Decode(&srcName); err != nil { return err diff --git a/router/surrogate_gossiper.go b/router/surrogate_gossiper.go new file mode 100644 index 00000000..ea7f443d --- /dev/null +++ b/router/surrogate_gossiper.go @@ -0,0 +1,41 @@ +package router + +type SurrogateGossipData struct { + messages [][]byte +} + +func NewSurrogateGossipData(msg []byte) *SurrogateGossipData { + return &SurrogateGossipData{messages: [][]byte{msg}} +} + +func (d *SurrogateGossipData) Encode() [][]byte { + return d.messages +} + +func (d *SurrogateGossipData) Merge(other GossipData) { + d.messages = append(d.messages, other.(*SurrogateGossipData).messages...) +} + +// SurrogateGossiper ignores unicasts and relays broadcasts and gossips. + +type SurrogateGossiper struct{} + +func (*SurrogateGossiper) OnGossipUnicast(sender PeerName, msg []byte) error { + return nil +} + +func (*SurrogateGossiper) OnGossipBroadcast(update []byte) (GossipData, error) { + return NewSurrogateGossipData(update), nil +} + +func (*SurrogateGossiper) Gossip() GossipData { + return nil +} + +func (*SurrogateGossiper) OnGossip(update []byte) (GossipData, error) { + return NewSurrogateGossipData(update), nil +} + +var ( + surrogateGossiper SurrogateGossiper +)