Skip to content
Snippets Groups Projects
Commit b2461336 authored by Benjamin Wenger's avatar Benjamin Wenger
Browse files

fixed issue with ephemeral IDs, both deletion and thread handling, within the receptionID package

parent 451a2002
Branches
No related tags found
4 merge requests!510Release,!419rewrote the health tracker to both consider if there are waiting rounds and...,!394fixed issue with ephemeral IDs, both deletion and thread handling, within the receptionID package,!340Project/channels
...@@ -87,18 +87,8 @@ func (c *client) followNetwork(report ClientErrorReport, ...@@ -87,18 +87,8 @@ func (c *client) followNetwork(report ClientErrorReport,
stop.ToStopped() stop.ToStopped()
return return
case <-ticker.C: case <-ticker.C:
// get the list of identities to track
stream := c.rng.GetStream()
toTrack, err := c.Tracker.GetEphemeralIdentities(
int(c.param.MaxParallelIdentityTracks),
stream,
c.Space.GetAddressSpaceWithoutWait())
stream.Close()
if err != nil { operator := func(toTrack []receptionID.IdentityUse) error {
jww.ERROR.Printf("failed to get identities to track")
continue
}
// set up tracking tools // set up tracking tools
wg := &sync.WaitGroup{} wg := &sync.WaitGroup{}
...@@ -123,6 +113,23 @@ func (c *client) followNetwork(report ClientErrorReport, ...@@ -123,6 +113,23 @@ func (c *client) followNetwork(report ClientErrorReport,
//wait for all to complete //wait for all to complete
wg.Wait() wg.Wait()
return nil
}
// get the list of identities to track
stream := c.rng.GetStream()
err := c.Tracker.ForEach(
int(c.param.MaxParallelIdentityTracks),
stream,
c.Space.GetAddressSpaceWithoutWait(),
operator)
stream.Close()
if err != nil {
jww.ERROR.Printf("failed to operate on identities to "+
"track: %s", err)
continue
}
case <-TrackTicker.C: case <-TrackTicker.C:
numPolls := atomic.SwapUint64(c.tracker, 0) numPolls := atomic.SwapUint64(c.tracker, 0)
......
...@@ -160,46 +160,13 @@ func (s *Store) makeStoredReferences() []storedReference { ...@@ -160,46 +160,13 @@ func (s *Store) makeStoredReferences() []storedReference {
return identities[:i] return identities[:i]
} }
// GetIdentity will return a single identity. If none are available, it will // ForEach operates on 'n' identities randomly in a random order.
// return a fake one // if no identities exist, it will operate on a single fake identity
func (s *Store) GetIdentity(rng io.Reader, addressSize uint8) IdentityUse { func (s *Store) ForEach(n int, rng io.Reader,
s.mux.Lock() addressSize uint8, operate func([]IdentityUse) error) error {
defer s.mux.Unlock()
now := netTime.Now()
// Remove any now expired identities
s.prune(now)
var identity IdentityUse
var err error
// If the list is empty, then return a randomly generated identity to poll
// with so that we can continue tracking the network and to further
// obfuscate network identities.
if len(s.active) == 0 {
identity, err = generateFakeIdentity(rng, addressSize, now)
if err != nil {
jww.FATAL.Panicf(
"Failed to generate a new ID when none available: %+v", err)
}
} else {
identity, err = s.selectIdentity(rng, now)
if err != nil {
jww.FATAL.Panicf("Failed to select an ID: %+v", err)
}
}
return identity
}
// GetIdentities will return up to 'n' identities randomly in a random order.
// if no identities exist, it will return a single fake identity
func (s *Store) GetIdentities(n int, rng io.Reader,
addressSize uint8) ([]IdentityUse, error) {
if n < 1 { if n < 1 {
return nil, InvalidRequestedNumIdentities return InvalidRequestedNumIdentities
} }
s.mux.Lock() s.mux.Lock()
...@@ -231,7 +198,8 @@ func (s *Store) GetIdentities(n int, rng io.Reader, ...@@ -231,7 +198,8 @@ func (s *Store) GetIdentities(n int, rng io.Reader,
} }
} }
return identities, nil // do the passed operation on all identities
return operate(identities)
} }
func (s *Store) AddIdentity(identity Identity) error { func (s *Store) AddIdentity(identity Identity) error {
...@@ -274,7 +242,8 @@ func (s *Store) RemoveIdentity(ephID ephemeral.Id) { ...@@ -274,7 +242,8 @@ func (s *Store) RemoveIdentity(ephID ephemeral.Id) {
s.mux.Lock() s.mux.Lock()
defer s.mux.Unlock() defer s.mux.Unlock()
for i, inQuestion := range s.active { for i := 0; i < len(s.active); i++ {
inQuestion := s.active[i]
if inQuestion.EphId == ephID { if inQuestion.EphId == ephID {
s.active = append(s.active[:i], s.active[i+1:]...) s.active = append(s.active[:i], s.active[i+1:]...)
...@@ -290,6 +259,8 @@ func (s *Store) RemoveIdentity(ephID ephemeral.Id) { ...@@ -290,6 +259,8 @@ func (s *Store) RemoveIdentity(ephID ephemeral.Id) {
} }
} }
i--
return return
} }
} }
...@@ -300,7 +271,8 @@ func (s *Store) RemoveIdentities(source *id.ID) { ...@@ -300,7 +271,8 @@ func (s *Store) RemoveIdentities(source *id.ID) {
defer s.mux.Unlock() defer s.mux.Unlock()
doSave := false doSave := false
for i, inQuestion := range s.active { for i := 0; i < len(s.active); i++ {
inQuestion := s.active[i]
if inQuestion.Source.Cmp(source) { if inQuestion.Source.Cmp(source) {
s.active = append(s.active[:i], s.active[i+1:]...) s.active = append(s.active[:i], s.active[i+1:]...)
...@@ -310,6 +282,7 @@ func (s *Store) RemoveIdentities(source *id.ID) { ...@@ -310,6 +282,7 @@ func (s *Store) RemoveIdentities(source *id.ID) {
} }
doSave = doSave || !inQuestion.Ephemeral doSave = doSave || !inQuestion.Ephemeral
i--
} }
} }
if doSave { if doSave {
......
...@@ -151,38 +151,6 @@ func TestStore_makeStoredReferences(t *testing.T) { ...@@ -151,38 +151,6 @@ func TestStore_makeStoredReferences(t *testing.T) {
} }
} }
func TestStore_GetIdentity(t *testing.T) {
kv := versioned.NewKV(ekv.MakeMemstore())
s := NewOrLoadStore(kv)
prng := rand.New(rand.NewSource(42))
testID, err := generateFakeIdentity(prng, 15, netTime.Now())
if err != nil {
t.Fatalf("Failed to generate fake ID: %+v", err)
}
if s.AddIdentity(testID.Identity) != nil {
t.Errorf("AddIdentity() produced an error: %+v", err)
}
idu := s.GetIdentity(prng, 15)
if !testID.Equal(idu.Identity) {
t.Errorf("GetIdentity() did not return the expected Identity."+
"\nexpected: %s\nreceived: %s", testID, idu)
}
}
func TestStore_GetIdentity_NoIdentities(t *testing.T) {
kv := versioned.NewKV(ekv.MakeMemstore())
s := NewOrLoadStore(kv)
prng := rand.New(rand.NewSource(42))
idu := s.GetIdentity(prng, 15)
if !idu.Fake {
t.Errorf("GetIdentity() did not return a fake identity")
}
}
func TestStore_GetIdentities(t *testing.T) { func TestStore_GetIdentities(t *testing.T) {
kv := versioned.NewKV(ekv.MakeMemstore()) kv := versioned.NewKV(ekv.MakeMemstore())
s := NewOrLoadStore(kv) s := NewOrLoadStore(kv)
...@@ -207,7 +175,12 @@ func TestStore_GetIdentities(t *testing.T) { ...@@ -207,7 +175,12 @@ func TestStore_GetIdentities(t *testing.T) {
} }
//get one //get one
idu, err := s.GetIdentities(1, prng, 15) var idu []IdentityUse
o := func(a []IdentityUse) error {
idu = a
return nil
}
err := s.ForEach(1, prng, 15, o)
if err != nil { if err != nil {
t.Errorf("GetIdentity() produced an error: %+v", err) t.Errorf("GetIdentity() produced an error: %+v", err)
} }
...@@ -218,7 +191,7 @@ func TestStore_GetIdentities(t *testing.T) { ...@@ -218,7 +191,7 @@ func TestStore_GetIdentities(t *testing.T) {
} }
//get three //get three
idu, err = s.GetIdentities(3, prng, 15) err = s.ForEach(3, prng, 15, o)
if err != nil { if err != nil {
t.Errorf("GetIdentity() produced an error: %+v", err) t.Errorf("GetIdentity() produced an error: %+v", err)
} }
...@@ -235,7 +208,7 @@ func TestStore_GetIdentities(t *testing.T) { ...@@ -235,7 +208,7 @@ func TestStore_GetIdentities(t *testing.T) {
} }
//get ten //get ten
idu, err = s.GetIdentities(10, prng, 15) err = s.ForEach(10, prng, 15, o)
if err != nil { if err != nil {
t.Errorf("GetIdentity() produced an error: %+v", err) t.Errorf("GetIdentity() produced an error: %+v", err)
} }
...@@ -252,7 +225,7 @@ func TestStore_GetIdentities(t *testing.T) { ...@@ -252,7 +225,7 @@ func TestStore_GetIdentities(t *testing.T) {
} }
//get fifty //get fifty
idu, err = s.GetIdentities(50, prng, 15) err = s.ForEach(50, prng, 15, o)
if err != nil { if err != nil {
t.Errorf("GetIdentity() produced an error: %+v", err) t.Errorf("GetIdentity() produced an error: %+v", err)
} }
...@@ -269,7 +242,7 @@ func TestStore_GetIdentities(t *testing.T) { ...@@ -269,7 +242,7 @@ func TestStore_GetIdentities(t *testing.T) {
} }
//get 100 //get 100
idu, err = s.GetIdentities(100, prng, 15) err = s.ForEach(100, prng, 15, o)
if err != nil { if err != nil {
t.Errorf("GetIdentity() produced an error: %+v", err) t.Errorf("GetIdentity() produced an error: %+v", err)
} }
...@@ -286,7 +259,7 @@ func TestStore_GetIdentities(t *testing.T) { ...@@ -286,7 +259,7 @@ func TestStore_GetIdentities(t *testing.T) {
} }
//get 1000, should only return 100 //get 1000, should only return 100
idu, err = s.GetIdentities(1000, prng, 15) err = s.ForEach(1000, prng, 15, o)
if err != nil { if err != nil {
t.Errorf("GetIdentity() produced an error: %+v", err) t.Errorf("GetIdentity() produced an error: %+v", err)
} }
...@@ -304,7 +277,13 @@ func TestStore_GetIdentities(t *testing.T) { ...@@ -304,7 +277,13 @@ func TestStore_GetIdentities(t *testing.T) {
// get 100 a second time and make sure the order is not the same as a // get 100 a second time and make sure the order is not the same as a
// smoke test that the shuffle is working // smoke test that the shuffle is working
idu2, err := s.GetIdentities(1000, prng, 15) var idu2 []IdentityUse
o2 := func(a []IdentityUse) error {
idu2 = a
return nil
}
err = s.ForEach(1000, prng, 15, o2)
if err != nil { if err != nil {
t.Errorf("GetIdentity() produced an error: %+v", err) t.Errorf("GetIdentity() produced an error: %+v", err)
} }
...@@ -329,7 +308,13 @@ func TestStore_GetIdentities_NoIdentities(t *testing.T) { ...@@ -329,7 +308,13 @@ func TestStore_GetIdentities_NoIdentities(t *testing.T) {
s := NewOrLoadStore(kv) s := NewOrLoadStore(kv)
prng := rand.New(rand.NewSource(42)) prng := rand.New(rand.NewSource(42))
idu, err := s.GetIdentities(5, prng, 15) var idu []IdentityUse
o := func(a []IdentityUse) error {
idu = a
return nil
}
err := s.ForEach(5, prng, 15, o)
if err != nil { if err != nil {
t.Errorf("GetIdentities() produced an error: %+v", err) t.Errorf("GetIdentities() produced an error: %+v", err)
} }
...@@ -350,27 +335,31 @@ func TestStore_GetIdentities_BadNum(t *testing.T) { ...@@ -350,27 +335,31 @@ func TestStore_GetIdentities_BadNum(t *testing.T) {
s := NewOrLoadStore(kv) s := NewOrLoadStore(kv)
prng := rand.New(rand.NewSource(42)) prng := rand.New(rand.NewSource(42))
_, err := s.GetIdentities(0, prng, 15) o := func(a []IdentityUse) error {
return nil
}
err := s.ForEach(0, prng, 15, o)
if err == nil { if err == nil {
t.Errorf("GetIdentities() shoud error with bad num value") t.Errorf("GetIdentities() shoud error with bad num value")
} }
_, err = s.GetIdentities(-1, prng, 15) err = s.ForEach(-1, prng, 15, o)
if err == nil { if err == nil {
t.Errorf("GetIdentities() shoud error with bad num value") t.Errorf("GetIdentities() shoud error with bad num value")
} }
_, err = s.GetIdentities(-100, prng, 15) err = s.ForEach(-100, prng, 15, o)
if err == nil { if err == nil {
t.Errorf("GetIdentities() shoud error with bad num value") t.Errorf("GetIdentities() shoud error with bad num value")
} }
_, err = s.GetIdentities(-1000000, prng, 15) err = s.ForEach(-1000000, prng, 15, o)
if err == nil { if err == nil {
t.Errorf("GetIdentities() shoud error with bad num value") t.Errorf("GetIdentities() shoud error with bad num value")
} }
_, err = s.GetIdentities(math.MinInt64, prng, 15) err = s.ForEach(math.MinInt64, prng, 15, o)
if err == nil { if err == nil {
t.Errorf("GetIdentities() shoud error with bad num value") t.Errorf("GetIdentities() shoud error with bad num value")
} }
......
...@@ -49,8 +49,8 @@ type Tracker interface { ...@@ -49,8 +49,8 @@ type Tracker interface {
StartProcesses() stoppable.Stoppable StartProcesses() stoppable.Stoppable
AddIdentity(id *id.ID, validUntil time.Time, persistent bool) AddIdentity(id *id.ID, validUntil time.Time, persistent bool)
RemoveIdentity(id *id.ID) RemoveIdentity(id *id.ID)
GetEphemeralIdentity(rng io.Reader, addressSize uint8) receptionID.IdentityUse ForEach(n int, rng io.Reader, addressSize uint8,
GetEphemeralIdentities(n int, rng io.Reader, addressSize uint8) ([]receptionID.IdentityUse, error) operator func([]receptionID.IdentityUse) error) error
GetIdentity(get *id.ID) (TrackedID, error) GetIdentity(get *id.ID) (TrackedID, error)
} }
...@@ -143,20 +143,14 @@ func (t *manager) RemoveIdentity(id *id.ID) { ...@@ -143,20 +143,14 @@ func (t *manager) RemoveIdentity(id *id.ID) {
t.deleteIdentity <- id t.deleteIdentity <- id
} }
// GetEphemeralIdentity returns an ephemeral Identity to poll the network with. // ForEach passes a fisher-yates shuffled list of up to 'num'
// It will return a fake identity if none are available. // ephemeral identities into the operation function. It will pass a
func (t *manager) GetEphemeralIdentity(rng io.Reader, // fake identity if none are available
addressSize uint8) receptionID.IdentityUse {
return t.ephemeral.GetIdentity(rng, addressSize)
}
// GetEphemeralIdentities returns a fisher-yates shuffled list of up to 'num'
// ephemeral identities. It will return a fake identity if none are available
// and less than 'num' if less than 'num' are available. // and less than 'num' if less than 'num' are available.
// 'num' must be positive non-zero // 'num' must be positive non-zero
func (t *manager) GetEphemeralIdentities(n int, rng io.Reader, addressSize uint8) ( func (t *manager) ForEach(n int, rng io.Reader, addressSize uint8,
[]receptionID.IdentityUse, error) { operator func([]receptionID.IdentityUse) error) error {
return t.ephemeral.GetIdentities(n, rng, addressSize) return t.ephemeral.ForEach(n, rng, addressSize, operator)
} }
// GetIdentity returns a currently tracked identity // GetIdentity returns a currently tracked identity
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment