diff --git a/connect/connect.go b/connect/connect.go index 764fc1ea1094d188389ccd53f6b9a9078859147a..86ba71b9cc825d06c50bceef96ea886277ebcc8d 100644 --- a/connect/connect.go +++ b/connect/connect.go @@ -28,9 +28,10 @@ import ( "time" ) -// Connection is a wrapper for the E2E and auth packages -// and automatically establishes an E2E partnership with a partner. -// You can then use this interface to send to and receive from the newly-established partner. +// Connection is a wrapper for the E2E and auth packages. +// It can be used to automatically establish an E2E partnership +// with a partner.Manager, or be built from an existing E2E partnership. +// You can then use this interface to send to and receive from the newly-established partner.Manager. type Connection interface { // Closer deletes this Connection's partner.Manager and releases resources io.Closer @@ -75,14 +76,14 @@ func GetDefaultParams() Params { // Connect performs auth key negotiation with the given recipient, // and returns a Connection object for the newly-created partner.Manager // This function is to be used sender-side and will block until the partner.Manager is confirmed -func Connect(recipient contact.Contact, myID *id.ID, rng *fastRNG.StreamGenerator, +func Connect(recipient contact.Contact, myId *id.ID, rng *fastRNG.StreamGenerator, grp *cyclic.Group, net cmix.Client, p Params) (Connection, error) { // Build an ephemeral KV kv := versioned.NewKV(ekv.MakeMemstore()) // Build E2e handler - e2eHandler, err := clientE2e.Load(kv, net, myID, grp, rng, p.event) + e2eHandler, err := clientE2e.Load(kv, net, myId, grp, rng, p.event) if err != nil { return nil, err } @@ -122,8 +123,60 @@ func Connect(recipient contact.Contact, myID *id.ID, rng *fastRNG.StreamGenerato }, nil } +// WaitForConnections assembles a Connection object on the reception-side +// whenever an E2E partnership with a partner.Manager is established. +// and sends it to the given connectionListener. Should be run in its own thread. +func WaitForConnections(connectionListener chan Connection, + myId *id.ID, rng *fastRNG.StreamGenerator, grp *cyclic.Group, net cmix.Client, p Params) { + + // Build an ephemeral KV + kv := versioned.NewKV(ekv.MakeMemstore()) + + // Build E2e handler + e2eHandler, err := clientE2e.Load(kv, net, myId, grp, rng, p.event) + if err != nil { + jww.ERROR.Printf("Unable to WaitForConnections: %+v", err) + return + } + + // Build callback for E2E negotiation + callback := GetConnectionCallback() + + // Build auth object for E2E negotiation + _, err = auth.NewState(kv, net, e2eHandler, + rng, p.event, p.auth, callback, nil) + if err != nil { + jww.ERROR.Printf("Unable to WaitForConnections: %+v", err) + return + } + + for { + // Block waiting for incoming auth request + jww.DEBUG.Printf("Connection waiting for auth request to be received...") + select { + case newPartnerId := <-callback.confirmPartner: + jww.DEBUG.Printf("Connection auth request for %s confirmed", newPartnerId.String()) + + // After confirmation, get the new partner + newPartner, err := e2eHandler.GetPartner(newPartnerId) + if err != nil { + jww.ERROR.Printf("Unable to establish new Connection with partner %s: %+v", + err, newPartnerId.String()) + continue + } + + connectionListener <- &handler{ + partner: newPartner, + params: p, + net: net, + e2e: e2eHandler, + } + } + } +} + // ConnectWithPartner assembles a Connection object on the reception-side -// after an E2E partnership has already been confirmed +// after an E2E partnership has already been confirmed with the given partner.Manager func ConnectWithPartner(partner partner.Manager, e2eHandler clientE2e.Handler, net cmix.Client, p Params) Connection { return &handler{