From 8e36f70a6572870f1fc43a984cad50c7d16d944a Mon Sep 17 00:00:00 2001 From: Benjamin Wenger <ben@elixxir.ioo> Date: Wed, 30 Mar 2022 14:39:01 -0700 Subject: [PATCH] finished sende2e, starting on rekey --- api/client.go | 4 +- e2e/manager.go | 28 +++- e2e/params.go | 60 +++++++ e2e/parse/partition.go | 2 +- e2e/processor.go | 4 +- e2e/ratchet/partner/session/cypher.go | 22 +-- e2e/ratchet/store.go | 16 +- {keyExchange => e2e/rekey}/confirm.go | 16 +- {keyExchange => e2e/rekey}/confirm_test.go | 2 +- {keyExchange => e2e/rekey}/exchange.go | 5 +- {keyExchange => e2e/rekey}/exchange_test.go | 2 +- {keyExchange => e2e/rekey}/generate.sh | 0 {keyExchange => e2e/rekey}/rekey.go | 2 +- {keyExchange => e2e/rekey}/rekey_test.go | 2 +- {keyExchange => e2e/rekey}/trigger.go | 2 +- {keyExchange => e2e/rekey}/trigger_test.go | 2 +- {keyExchange => e2e/rekey}/utils_test.go | 2 +- {keyExchange => e2e/rekey}/xchange.pb.go | 2 +- {keyExchange => e2e/rekey}/xchange.proto | 0 e2e/sendE2E.go | 171 ++++++++++++++++++++ go.mod | 2 +- go.sum | 2 + network/params.go | 2 + 23 files changed, 300 insertions(+), 50 deletions(-) create mode 100644 e2e/params.go rename {keyExchange => e2e/rekey}/confirm.go (88%) rename {keyExchange => e2e/rekey}/confirm_test.go (99%) rename {keyExchange => e2e/rekey}/exchange.go (93%) rename {keyExchange => e2e/rekey}/exchange_test.go (99%) rename {keyExchange => e2e/rekey}/generate.sh (100%) mode change 100755 => 100644 rename {keyExchange => e2e/rekey}/rekey.go (99%) rename {keyExchange => e2e/rekey}/rekey_test.go (98%) rename {keyExchange => e2e/rekey}/trigger.go (99%) rename {keyExchange => e2e/rekey}/trigger_test.go (99%) rename {keyExchange => e2e/rekey}/utils_test.go (99%) rename {keyExchange => e2e/rekey}/xchange.pb.go (99%) rename {keyExchange => e2e/rekey}/xchange.proto (100%) create mode 100644 e2e/sendE2E.go diff --git a/api/client.go b/api/client.go index 17ea0a289..a9e632ee8 100644 --- a/api/client.go +++ b/api/client.go @@ -13,12 +13,12 @@ import ( jww "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/client/auth" "gitlab.com/elixxir/client/catalog" + keyExchange2 "gitlab.com/elixxir/client/e2e/rekey" "gitlab.com/elixxir/client/event" "gitlab.com/elixxir/client/interfaces" "gitlab.com/elixxir/client/interfaces/params" "gitlab.com/elixxir/client/interfaces/preimage" "gitlab.com/elixxir/client/interfaces/user" - "gitlab.com/elixxir/client/keyExchange" "gitlab.com/elixxir/client/network" "gitlab.com/elixxir/client/registration" "gitlab.com/elixxir/client/stoppable" @@ -564,7 +564,7 @@ func (c *Client) registerFollower() error { //register the key exchange service keyXchange := func() (stoppable.Stoppable, error) { - return keyExchange.Start(c.switchboard, c.storage, c.network, c.parameters.Rekey) + return keyExchange2.Start(c.switchboard, c.storage, c.network, c.parameters.Rekey) } err = c.followerServices.add(keyXchange) diff --git a/e2e/manager.go b/e2e/manager.go index 5871e7b06..f29c60f72 100644 --- a/e2e/manager.go +++ b/e2e/manager.go @@ -4,9 +4,11 @@ import ( "gitlab.com/elixxir/client/e2e/parse" "gitlab.com/elixxir/client/e2e/ratchet" "gitlab.com/elixxir/client/e2e/receive" + "gitlab.com/elixxir/client/event" "gitlab.com/elixxir/client/network" "gitlab.com/elixxir/client/storage/versioned" "gitlab.com/elixxir/crypto/cyclic" + "gitlab.com/elixxir/crypto/fastRNG" "gitlab.com/xx_network/primitives/id" ) @@ -16,8 +18,32 @@ type Manager struct { partitioner parse.Partitioner net network.Manager myID *id.ID + rng *fastRNG.StreamGenerator + events event.Manager + grp *cyclic.Group } -func InitManager(kv *versioned.KV, myID *id.ID, privKey *cyclic.Int) { +//Init Creates stores. After calling, use load +func Init(kv *versioned.KV, myID *id.ID, privKey *cyclic.Int, grp *cyclic.Group) error { + return ratchet.New(kv, myID, privKey, grp) +} +// Load returns an e2e manager from storage +func Load(kv *versioned.KV, net network.Manager, myID *id.ID, + grp *cyclic.Group, rng *fastRNG.StreamGenerator, events event.Manager) (*Manager, error) { + m := &Manager{ + Switchboard: receive.New(), + partitioner: parse.NewPartitioner(kv, net.GetMaxMessageLength()), + net: net, + myID: myID, + events: events, + grp: grp, + } + var err error + m.Ratchet, err = ratchet.Load(kv, myID, grp, + &fpGenerator{m}, net, rng) + if err != nil { + return nil, err + } + return m, nil } diff --git a/e2e/params.go b/e2e/params.go new file mode 100644 index 000000000..f897548a9 --- /dev/null +++ b/e2e/params.go @@ -0,0 +1,60 @@ +package e2e + +import ( + "encoding/json" + "gitlab.com/elixxir/client/catalog" + "gitlab.com/elixxir/client/network" + "time" +) + +type Params struct { + // Tag to use to generate the service. + ServiceTag string + // Often, for notifications purposes, all messages except the last should + // use a silent service. This allows a + LastServiceTag string + + // The parameters adjust how the code behaves if there are not keys available. + // the number of times the code will attempt to get a key to encrypt with + KeyGetRetryCount uint + // Delay between attempting to get kets + KeyGeRetryDelay time.Duration + + //Underlying cmix tags. + // Note: if critical is true, an alternative critical messages system within + // e2e will be used which preserves privacy + CMIX network.CMIXParams + + //Authorizes the message to use a key reserved for rekeying. Do not use + //unless sending a rekey + Rekey bool +} + +func GetDefaultParams() Params { + return Params{ + ServiceTag: catalog.Silent, + LastServiceTag: catalog.E2e, + + KeyGetRetryCount: 10, + KeyGeRetryDelay: 500 * time.Millisecond, + + CMIX: network.GetDefaultCMIXParams(), + Rekey: false, + } +} +func (e Params) Marshal() ([]byte, error) { + return json.Marshal(e) +} + +// GetParameters Obtain default E2E parameters, or override with +// given parameters if set +func GetParameters(params string) (Params, error) { + p := GetDefaultParams() + if len(params) > 0 { + err := json.Unmarshal([]byte(params), &p) + if err != nil { + return Params{}, err + } + } + return p, nil +} diff --git a/e2e/parse/partition.go b/e2e/parse/partition.go index 06e10bcae..cb72eec3e 100644 --- a/e2e/parse/partition.go +++ b/e2e/parse/partition.go @@ -31,7 +31,7 @@ type Partitioner struct { partition *partition.Store } -func NewPartitioner(messageSize int, kv *versioned.KV) Partitioner { +func NewPartitioner(kv *versioned.KV, messageSize int) Partitioner { p := Partitioner{ baseMessageSize: messageSize, firstContentsSize: messageSize - firstHeaderLen, diff --git a/e2e/processor.go b/e2e/processor.go index e86e1a20b..04c6b68a9 100644 --- a/e2e/processor.go +++ b/e2e/processor.go @@ -19,7 +19,7 @@ func (p *processor) Process(ecrMsg format.Message, receptionID receptionID.Ephem defer p.cy.Use() //decrypt - msg, err := p.cy.Decrypt(ecrMsg) + contents, err := p.cy.Decrypt(ecrMsg) if err != nil { jww.ERROR.Printf("Decryption Failed of %s (fp: %s), dropping: %+v", ecrMsg.Digest(), p.cy.Fingerprint(), err) @@ -29,7 +29,7 @@ func (p *processor) Process(ecrMsg format.Message, receptionID receptionID.Ephem //Parse sess := p.cy.GetSession() message, done := p.m.partitioner.HandlePartition(sess.GetPartner(), - msg.GetContents(), sess.GetRelationshipFingerprint()) + contents, sess.GetRelationshipFingerprint()) if done { message.RecipientID = receptionID.Source diff --git a/e2e/ratchet/partner/session/cypher.go b/e2e/ratchet/partner/session/cypher.go index 5a8f352b9..fe713eb08 100644 --- a/e2e/ratchet/partner/session/cypher.go +++ b/e2e/ratchet/partner/session/cypher.go @@ -86,45 +86,37 @@ func (k *Cypher) Fingerprint() format.Fingerprint { // the E2E key to encrypt msg to its intended recipient // It also properly populates the associated data, including the MAC, fingerprint, // and encrypted timestamp -func (k *Cypher) Encrypt(msg format.Message) format.Message { +func (k *Cypher) Encrypt(contents []byte) (ecrContents, mac []byte) { fp := k.Fingerprint() key := k.generateKey() - // set the fingerprint - msg.SetKeyFP(fp) - // encrypt the payload - encPayload := e2eCrypto.Crypt(key, fp, msg.GetContents()) - msg.SetContents(encPayload) + ecrContents = e2eCrypto.Crypt(key, fp, contents) // create the MAC // MAC is HMAC(key, ciphertext) // Currently, the MAC doesn't include any of the associated data - MAC := hash.CreateHMAC(encPayload, key[:]) - msg.SetMac(MAC) + mac = hash.CreateHMAC(ecrContents, key[:]) - return msg + return ecrContents, mac } // Decrypt uses the E2E key to decrypt the message // It returns an error in case of HMAC verification failure // or in case of a decryption error (related to padding) -func (k *Cypher) Decrypt(msg format.Message) (format.Message, error) { +func (k *Cypher) Decrypt(msg format.Message) ([]byte, error) { fp := k.Fingerprint() key := k.generateKey() // Verify the MAC is correct if !hash.VerifyHMAC(msg.GetContents(), msg.GetMac(), key[:]) { - return format.Message{}, errors.New("HMAC verification failed for E2E message") + return nil, errors.New("HMAC verification failed for E2E message") } // Decrypt the payload decryptedPayload := e2eCrypto.Crypt(key, fp, msg.GetContents()) - //put the decrypted payload back in the message - msg.SetContents(decryptedPayload) - - return msg, nil + return decryptedPayload, nil } // Use sets the key as used. It cannot be used again. diff --git a/e2e/ratchet/store.go b/e2e/ratchet/store.go index 0cf1ca902..b300a7c44 100644 --- a/e2e/ratchet/store.go +++ b/e2e/ratchet/store.go @@ -55,13 +55,12 @@ type Ratchet struct { kv *versioned.KV } -// NewRatchet creates a new store for the passed user id and private key. +// New creates a new store for the passed user id and private key. // The store can then be accessed by calling LoadStore. // Does not create at a unique prefix, if multiple Ratchets are needed, make // sure to add a uint prefix to the KV before instantiation. -func NewRatchet(kv *versioned.KV, privKey *cyclic.Int, - myID *id.ID, grp *cyclic.Group, cyHandler session.CypherHandler, - services Services, rng *fastRNG.StreamGenerator) error { +func New(kv *versioned.KV, myID *id.ID, privKey *cyclic.Int, + grp *cyclic.Group) error { // Generate public key pubKey := diffieHellman.GeneratePublicKey(privKey, grp) @@ -79,10 +78,7 @@ func NewRatchet(kv *versioned.KV, privKey *cyclic.Int, kv: kv, - cyHandler: cyHandler, - grp: grp, - rng: rng, - sInteface: services, + grp: grp, } err := util.StoreCyclicKey(kv, pubKey, pubKeyKey) @@ -100,8 +96,8 @@ func NewRatchet(kv *versioned.KV, privKey *cyclic.Int, return r.save() } -// LoadRatchet loads an extant ratchet from disk -func LoadRatchet(kv *versioned.KV, myID *id.ID, grp *cyclic.Group, +// Load loads an extant ratchet from disk +func Load(kv *versioned.KV, myID *id.ID, grp *cyclic.Group, cyHandler session.CypherHandler, services Services, rng *fastRNG.StreamGenerator) ( *Ratchet, error) { kv = kv.Prefix(packagePrefix) diff --git a/keyExchange/confirm.go b/e2e/rekey/confirm.go similarity index 88% rename from keyExchange/confirm.go rename to e2e/rekey/confirm.go index 3ff7e3183..a8d791363 100644 --- a/keyExchange/confirm.go +++ b/e2e/rekey/confirm.go @@ -5,19 +5,19 @@ // LICENSE file // /////////////////////////////////////////////////////////////////////////////// -package keyExchange +package rekey import ( "github.com/golang/protobuf/proto" "github.com/pkg/errors" jww "github.com/spf13/jwalterweatherman" + "gitlab.com/elixxir/client/e2e/ratchet" session2 "gitlab.com/elixxir/client/e2e/ratchet/partner/session" - "gitlab.com/elixxir/client/interfaces/message" + "gitlab.com/elixxir/client/e2e/receive" "gitlab.com/elixxir/client/stoppable" - "gitlab.com/elixxir/client/storage" ) -func startConfirm(sess *storage.Session, c chan message.Receive, +func startConfirm(ratchet *ratchet.Ratchet, c chan receive.Message, stop *stoppable.Single, cleanup func()) { for true { select { @@ -26,14 +26,14 @@ func startConfirm(sess *storage.Session, c chan message.Receive, stop.ToStopped() return case confirmation := <-c: - handleConfirm(sess, confirmation) + handleConfirm(ratchet, confirmation) } } } -func handleConfirm(sess *storage.Session, confirmation message.Receive) { +func handleConfirm(ratchet *ratchet.Ratchet, confirmation receive.Message) { //ensure the message was encrypted properly - if confirmation.Encryption != message.E2E { + if !confirmation.Encrypted { jww.ERROR.Printf( "[REKEY] Received non-e2e encrypted Key Exchange "+ "confirm from partner %s", confirmation.Sender) @@ -41,7 +41,7 @@ func handleConfirm(sess *storage.Session, confirmation message.Receive) { } //get the partner - partner, err := sess.E2e().GetPartner(confirmation.Sender) + partner, err := ratchet.GetPartner(confirmation.Sender) if err != nil { jww.ERROR.Printf( "[REKEY] Received Key Exchange Confirmation with unknown "+ diff --git a/keyExchange/confirm_test.go b/e2e/rekey/confirm_test.go similarity index 99% rename from keyExchange/confirm_test.go rename to e2e/rekey/confirm_test.go index 87c453093..1d47e0d69 100644 --- a/keyExchange/confirm_test.go +++ b/e2e/rekey/confirm_test.go @@ -5,7 +5,7 @@ // LICENSE file // /////////////////////////////////////////////////////////////////////////////// -package keyExchange +package rekey import ( "github.com/cloudflare/circl/dh/sidh" diff --git a/keyExchange/exchange.go b/e2e/rekey/exchange.go similarity index 93% rename from keyExchange/exchange.go rename to e2e/rekey/exchange.go index 121d3b2b4..620d63087 100644 --- a/keyExchange/exchange.go +++ b/e2e/rekey/exchange.go @@ -5,9 +5,10 @@ // LICENSE file // /////////////////////////////////////////////////////////////////////////////// -package keyExchange +package rekey import ( + "gitlab.com/elixxir/client/e2e/receive" "gitlab.com/elixxir/client/interfaces" "gitlab.com/elixxir/client/interfaces/message" "gitlab.com/elixxir/client/interfaces/params" @@ -21,7 +22,7 @@ const keyExchangeTriggerName = "KeyExchangeTrigger" const keyExchangeConfirmName = "KeyExchangeConfirm" const keyExchangeMulti = "KeyExchange" -func Start(switchboard *switchboard.Switchboard, sess *storage.Session, net interfaces.NetworkManager, +func Start(switchboard *receive.Switchboard, sess *storage.Session, net interfaces.NetworkManager, params params.Rekey) (stoppable.Stoppable, error) { // register the rekey trigger thread diff --git a/keyExchange/exchange_test.go b/e2e/rekey/exchange_test.go similarity index 99% rename from keyExchange/exchange_test.go rename to e2e/rekey/exchange_test.go index 04d6c4ec2..4851e17d3 100644 --- a/keyExchange/exchange_test.go +++ b/e2e/rekey/exchange_test.go @@ -5,7 +5,7 @@ // LICENSE file // /////////////////////////////////////////////////////////////////////////////// -package keyExchange +package rekey import ( "fmt" diff --git a/keyExchange/generate.sh b/e2e/rekey/generate.sh old mode 100755 new mode 100644 similarity index 100% rename from keyExchange/generate.sh rename to e2e/rekey/generate.sh diff --git a/keyExchange/rekey.go b/e2e/rekey/rekey.go similarity index 99% rename from keyExchange/rekey.go rename to e2e/rekey/rekey.go index e76f54652..888f85dad 100644 --- a/keyExchange/rekey.go +++ b/e2e/rekey/rekey.go @@ -5,7 +5,7 @@ // LICENSE file // /////////////////////////////////////////////////////////////////////////////// -package keyExchange +package rekey import ( "fmt" diff --git a/keyExchange/rekey_test.go b/e2e/rekey/rekey_test.go similarity index 98% rename from keyExchange/rekey_test.go rename to e2e/rekey/rekey_test.go index b507fc266..6a07e438d 100644 --- a/keyExchange/rekey_test.go +++ b/e2e/rekey/rekey_test.go @@ -5,7 +5,7 @@ // LICENSE file // /////////////////////////////////////////////////////////////////////////////// -package keyExchange +package rekey /* func TestRekey(t *testing.T) { diff --git a/keyExchange/trigger.go b/e2e/rekey/trigger.go similarity index 99% rename from keyExchange/trigger.go rename to e2e/rekey/trigger.go index 85e68e48b..85011845f 100644 --- a/keyExchange/trigger.go +++ b/e2e/rekey/trigger.go @@ -5,7 +5,7 @@ // LICENSE file // /////////////////////////////////////////////////////////////////////////////// -package keyExchange +package rekey import ( "fmt" diff --git a/keyExchange/trigger_test.go b/e2e/rekey/trigger_test.go similarity index 99% rename from keyExchange/trigger_test.go rename to e2e/rekey/trigger_test.go index 6391fbab0..2b568b2e2 100644 --- a/keyExchange/trigger_test.go +++ b/e2e/rekey/trigger_test.go @@ -5,7 +5,7 @@ // LICENSE file // /////////////////////////////////////////////////////////////////////////////// -package keyExchange +package rekey import ( "github.com/cloudflare/circl/dh/sidh" diff --git a/keyExchange/utils_test.go b/e2e/rekey/utils_test.go similarity index 99% rename from keyExchange/utils_test.go rename to e2e/rekey/utils_test.go index ed32032b4..2d4e7f709 100644 --- a/keyExchange/utils_test.go +++ b/e2e/rekey/utils_test.go @@ -5,7 +5,7 @@ // LICENSE file // /////////////////////////////////////////////////////////////////////////////// -package keyExchange +package rekey import ( "github.com/cloudflare/circl/dh/sidh" diff --git a/keyExchange/xchange.pb.go b/e2e/rekey/xchange.pb.go similarity index 99% rename from keyExchange/xchange.pb.go rename to e2e/rekey/xchange.pb.go index 7871a130b..a9b5f46ef 100644 --- a/keyExchange/xchange.pb.go +++ b/e2e/rekey/xchange.pb.go @@ -13,7 +13,7 @@ // protoc v3.15.6 // source: xchange.proto -package keyExchange +package rekey import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" diff --git a/keyExchange/xchange.proto b/e2e/rekey/xchange.proto similarity index 100% rename from keyExchange/xchange.proto rename to e2e/rekey/xchange.proto diff --git a/e2e/sendE2E.go b/e2e/sendE2E.go new file mode 100644 index 000000000..30acc83c9 --- /dev/null +++ b/e2e/sendE2E.go @@ -0,0 +1,171 @@ +package e2e + +import ( + "github.com/pkg/errors" + jww "github.com/spf13/jwalterweatherman" + "gitlab.com/elixxir/client/catalog" + "gitlab.com/elixxir/client/e2e/ratchet/partner/session" + keyExchange2 "gitlab.com/elixxir/client/e2e/rekey" + "gitlab.com/elixxir/client/network/message" + "gitlab.com/elixxir/client/stoppable" + "gitlab.com/elixxir/crypto/e2e" + "gitlab.com/elixxir/primitives/format" + "gitlab.com/xx_network/primitives/id" + "gitlab.com/xx_network/primitives/netTime" + "sync" + "time" +) + +func (m *Manager) SendE2E(mt catalog.MessageType, recipient *id.ID, + payload []byte, params Params) ([]id.Round, e2e.MessageID, time.Time, error) { + //timestamp the message + ts := netTime.Now() + + //partition the message + partitions, internalMsgId, err := m.partitioner.Partition(recipient, mt, ts, + payload) + if err != nil { + return nil, e2e.MessageID{}, time.Time{}, errors.WithMessage(err, "failed to send unsafe message") + } + + jww.INFO.Printf("E2E sending %d messages to %s", + len(partitions), recipient) + + //encrypt then send the partitions over cmix + roundIds := make([]id.Round, len(partitions)) + errCh := make(chan error, len(partitions)) + + // get the key manager for the partner + partner, err := m.Ratchet.GetPartner(recipient) + if err != nil { + return nil, e2e.MessageID{}, time.Time{}, errors.WithMessagef(err, + "Could not send End to End encrypted "+ + "message, no relationship found with %s", recipient) + } + + //return the rounds if everything send successfully + msgID := e2e.NewMessageID(partner.GetSendRelationshipFingerprint(), internalMsgId) + + wg := sync.WaitGroup{} + + for i, p := range partitions { + if mt != catalog.KeyExchangeTrigger { + // check if any rekeys need to happen and trigger them + keyExchange2.CheckKeyExchanges(m.Instance, m.SendE2E, + m.Events, m.Session, partner, + 1*time.Minute, stop) + } + + //get a key to end to end encrypt + var keyGetter func() (*session.Cypher, error) + if params.Rekey { + keyGetter = partner.PopRekeyCypher + } else { + keyGetter = partner.PopSendCypher + } + + //fixme: remove this wait, it is weird. Why is it here? we cant remember. + key, err := waitForKey(keyGetter, params.KeyGetRetryCount, + params.KeyGeRetryDelay, params.CMIX.Stop, recipient, + format.DigestContents(p), i) + if err != nil { + return nil, e2e.MessageID{}, time.Time{}, errors.WithMessagef(err, + "Failed to get key for end to end encryption") + } + + //end to end encrypt the cmix message + contentsEnc, mac := key.Encrypt(p) + + jww.INFO.Printf("E2E sending %d/%d to %s with key fp: %s, msgID: %s", + i+i, len(partitions), recipient, format.DigestContents(p), + key.Fingerprint(), msgID) + + //set up the service tags + var s message.Service + if i == len(partitions)-1 { + s = partner.MakeService(params.LastServiceTag) + } else { + s = partner.MakeService(params.ServiceTag) + } + + //send the cmix message, each partition in its own thread + wg.Add(1) + go func(i int) { + var err error + roundIds[i], _, err = m.net.SendCMIX(recipient, key.Fingerprint(), + s, contentsEnc, mac, params.CMIX) + if err != nil { + errCh <- err + } + wg.Done() + }(i) + } + + wg.Wait() + + //see if any parts failed to send + numFail, errRtn := getSendErrors(errCh) + if numFail > 0 { + jww.INFO.Printf("Failed to E2E send %d/%d to %s", + numFail, len(partitions), recipient) + return nil, e2e.MessageID{}, time.Time{}, errors.Errorf("Failed to E2E send %v/%v sub payloads:"+ + " %s", numFail, len(partitions), errRtn) + } else { + jww.INFO.Printf("Successfully E2E sent %d/%d to %s", + len(partitions)-numFail, len(partitions), recipient) + } + + //return the rounds if everything send successfully + jww.INFO.Printf("Successful E2E Send of %d messages to %s with msgID %s", + len(partitions), recipient, msgID) + return roundIds, msgID, ts, nil +} + +// waitForKey waits the designated ammount of time for a +func waitForKey(keyGetter func() (*session.Cypher, error), numAttempts uint, + wait time.Duration, stop *stoppable.Single, recipient *id.ID, + digest string, partition int) (*session.Cypher, error) { + key, err := keyGetter() + if err == nil { + return key, nil + } + + ticker := time.NewTicker(wait) + defer ticker.Stop() + + for keyTries := uint(1); err != nil && keyTries < numAttempts; keyTries++ { + jww.WARN.Printf("Out of sending keys for %s "+ + "(digest: %s, partition: %d), this can "+ + "happen when sending messages faster than "+ + "the client can negotiate keys. Please "+ + "adjust your e2e key parameters", + recipient, digest, partition) + + select { + case <-ticker.C: + key, err = keyGetter() + case <-stop.Quit(): + stop.ToStopped() + return nil, errors.Errorf("Stopped by stopper") + } + } + + return key, err +} + +// getSendErrors returns any errors on the error channel +func getSendErrors(c chan error) (int, string) { + var errRtn string + numFail := 0 + done := false + for !done { + select { + case err := <-c: + errRtn += err.Error() + numFail++ + default: + done = true + } + } + return numFail, errRtn +} diff --git a/go.mod b/go.mod index 101ca34e6..0d0456184 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( gitlab.com/elixxir/comms v0.0.4-0.20220308183624-c2183e687a03 gitlab.com/elixxir/crypto v0.0.7-0.20220328164108-c72388181116 gitlab.com/elixxir/ekv v0.1.6 - gitlab.com/elixxir/primitives v0.0.3-0.20220325212708-5e2a7a385db7 + gitlab.com/elixxir/primitives v0.0.3-0.20220330212736-cce83b5f948f gitlab.com/xx_network/comms v0.0.4-0.20220311192415-d95fe8906580 gitlab.com/xx_network/crypto v0.0.5-0.20220222212031-750f7e8a01f4 gitlab.com/xx_network/primitives v0.0.4-0.20220222211843-901fa4a2d72b diff --git a/go.sum b/go.sum index 59dc6cb4a..a28b5a590 100644 --- a/go.sum +++ b/go.sum @@ -297,6 +297,8 @@ gitlab.com/elixxir/primitives v0.0.3-0.20220222212109-d412a6e46623 h1:NzJ06KdJd3 gitlab.com/elixxir/primitives v0.0.3-0.20220222212109-d412a6e46623/go.mod h1:MtFIyJUQn9P7djzVlBpEYkPNnnWFTjZvw89swoXY+QM= gitlab.com/elixxir/primitives v0.0.3-0.20220325212708-5e2a7a385db7 h1:2yIEkxkPJboftkk/xiCONVP/FSl7Y3zOPpekvQ2dhO0= gitlab.com/elixxir/primitives v0.0.3-0.20220325212708-5e2a7a385db7/go.mod h1:MtFIyJUQn9P7djzVlBpEYkPNnnWFTjZvw89swoXY+QM= +gitlab.com/elixxir/primitives v0.0.3-0.20220330212736-cce83b5f948f h1:bOX9nsG+ihvZAUP2OimpM/0UNIcfz5tYlvQfS2IFUoU= +gitlab.com/elixxir/primitives v0.0.3-0.20220330212736-cce83b5f948f/go.mod h1:9Bb2+u+CDSwsEU5Droo6saDAXuBDvLRjexpBhPAYxhA= gitlab.com/xx_network/comms v0.0.0-20200805174823-841427dd5023/go.mod h1:owEcxTRl7gsoM8c3RQ5KAm5GstxrJp5tn+6JfQ4z5Hw= gitlab.com/xx_network/comms v0.0.4-0.20220223205228-7c4974139569/go.mod h1:isHnwem0v4rTcwwHP455FhVlFyPcHkHiVz+N3s/uCSI= gitlab.com/xx_network/comms v0.0.4-0.20220311192415-d95fe8906580 h1:IV0gDwdTxtCpc9Vkx7IeSStSqvG+0ZpF57X+OhTQDIM= diff --git a/network/params.go b/network/params.go index a37eaa3ad..a36dcb018 100644 --- a/network/params.go +++ b/network/params.go @@ -137,6 +137,8 @@ func GetDefaultCMIXParams() CMIXParams { RetryDelay: 1 * time.Second, SendTimeout: 3 * time.Second, DebugTag: "External", + //unused single so components that require one have a channel to wait on + Stop: stoppable.NewSingle("cmixParamsDefault"), } } -- GitLab