diff --git a/protocols/bgp/server/server.go b/protocols/bgp/server/server.go index 4015f44b78b834f9793fd8c469f1c0fd6d25e6df..db6ae24f310cf027114e5e95aee7fee3211aac8b 100644 --- a/protocols/bgp/server/server.go +++ b/protocols/bgp/server/server.go @@ -7,10 +7,9 @@ import ( "strings" "sync" - "github.com/bio-routing/bio-rd/routingtable/locRIB" - "github.com/bio-routing/bio-rd/config" "github.com/bio-routing/bio-rd/protocols/bgp/packet" + "github.com/bio-routing/bio-rd/routingtable/locRIB" log "github.com/sirupsen/logrus" ) diff --git a/routingtable/BUILD.bazel b/routingtable/BUILD.bazel index 22b4ef8c205b3e8b92490e7bb7df107b5fbb11d1..fdea62781ff59b143bf04d143ee5eae9385e0bc6 100644 --- a/routingtable/BUILD.bazel +++ b/routingtable/BUILD.bazel @@ -26,7 +26,7 @@ go_test( name = "go_default_test", srcs = [ "client_manager_test.go", - "contributing_asn_list_test.go", + "contributing_asn_list_test.go", "table_test.go", "trie_test.go", "update_helper_test.go", diff --git a/routingtable/contributing_asn_list.go b/routingtable/contributing_asn_list.go index f08058e28498fb9930cf8b90e76db3bdae381cfd..dd6b9885c14bc424e25b8abb910d43a410140fab 100644 --- a/routingtable/contributing_asn_list.go +++ b/routingtable/contributing_asn_list.go @@ -1,6 +1,8 @@ package routingtable import ( + "fmt" + "math" "sync" ) @@ -11,8 +13,8 @@ type contributingASN struct { // ContributingASNs contains a list of contributing ASN to a LocRIB to check ASPaths for possible routing loops. type ContributingASNs struct { - contributingASNs []*contributingASN - mu sync.RWMutex + contributingASNs []*contributingASN + contributingASNsLock sync.RWMutex } // NewContributingASNs creates a list of contributing ASNs to a LocRIB for routing loop prevention. @@ -26,12 +28,17 @@ func NewContributingASNs() *ContributingASNs { // Add a new ASN to the list of contributing ASNs or add the ref count of an existing one. func (c *ContributingASNs) Add(asn uint32) { - c.mu.RLock() - defer c.mu.RUnlock() + c.contributingASNsLock.Lock() + defer c.contributingASNsLock.Unlock() for _, cASN := range c.contributingASNs { if cASN.asn == asn { cASN.count++ + + if cASN.count == math.MaxUint32 { + panic(fmt.Sprintf("Contributing ASNs counter overflow triggered for AS %d. Dyning of shame.", asn)) + } + return } } @@ -44,27 +51,33 @@ func (c *ContributingASNs) Add(asn uint32) { // Remove a ASN to the list of contributing ASNs or decrement the ref count of an existing one. func (c *ContributingASNs) Remove(asn uint32) { - c.mu.RLock() - defer c.mu.RUnlock() + c.contributingASNsLock.Lock() + defer c.contributingASNsLock.Unlock() asnList := c.contributingASNs for i, cASN := range asnList { - if cASN.asn == asn { - cASN.count-- + if cASN.asn != asn { + continue + } - if cASN.count == 0 { - copy(asnList[i:], asnList[i+1:]) - asnList = asnList[:len(asnList)] - c.contributingASNs = asnList[:len(asnList)-1] - } - return + cASN.count-- + + if cASN.count == 0 { + copy(asnList[i:], asnList[i+1:]) + asnList = asnList[:len(asnList)] + c.contributingASNs = asnList[:len(asnList)-1] } + + return } } // IsContributingASN checks if a given ASN is part of the contributing ASNs func (c *ContributingASNs) IsContributingASN(asn uint32) bool { + c.contributingASNsLock.Lock() + defer c.contributingASNsLock.Unlock() + for _, cASN := range c.contributingASNs { if asn == cASN.asn { return true