diff --git a/pkg/client/client.go b/pkg/client/client.go index 90580791..d6cb8dae 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -13,6 +13,7 @@ import ( "github.com/Indra-Labs/indra/pkg/key/pub" "github.com/Indra-Labs/indra/pkg/key/signer" "github.com/Indra-Labs/indra/pkg/node" + "github.com/Indra-Labs/indra/pkg/nonce" "github.com/Indra-Labs/indra/pkg/slice" "github.com/Indra-Labs/indra/pkg/types" "github.com/Indra-Labs/indra/pkg/wire" @@ -47,10 +48,19 @@ type Client struct { *address.ReceiveCache Circuits Sessions + Confirms sync.Mutex *signer.KeySet qu.C } +type ConfirmHook func(cf *confirm.OnionSkin) + +type ConfirmCallback struct { + nonce.ID + Hook ConfirmHook +} + +type Confirms []ConfirmCallback func New(tpt ifc.Transport, hdrPrv *prv.Key, no *node.Node, nodes node.Nodes) (c *Client, e error) { @@ -94,40 +104,40 @@ func (cl *Client) runner() (out bool) { } switch on := onion.(type) { case *cipher.OnionSkin: - log.I.Ln(reflect.TypeOf(on)) + log.T.Ln(reflect.TypeOf(on)) cl.cipher(on, b, c) case *confirm.OnionSkin: - log.I.Ln(reflect.TypeOf(on)) + log.T.Ln(reflect.TypeOf(on)) cl.confirm(on, b, c) case *delay.OnionSkin: - log.I.Ln(reflect.TypeOf(on)) + log.T.Ln(reflect.TypeOf(on)) cl.delay(on, b, c) case *exit.OnionSkin: - log.I.Ln(reflect.TypeOf(on)) + log.T.Ln(reflect.TypeOf(on)) cl.exit(on, b, c) case *forward.OnionSkin: - log.I.Ln(reflect.TypeOf(on)) + log.T.Ln(reflect.TypeOf(on)) cl.forward(on, b, c) case *layer.OnionSkin: - log.I.Ln(reflect.TypeOf(on)) + log.T.Ln(reflect.TypeOf(on)) cl.layer(on, b, c) case *noop.OnionSkin: - log.I.Ln(reflect.TypeOf(on)) + log.T.Ln(reflect.TypeOf(on)) cl.noop(on, b, c) case *purchase.OnionSkin: - log.I.Ln(reflect.TypeOf(on)) + log.T.Ln(reflect.TypeOf(on)) cl.purchase(on, b, c) case *reverse.OnionSkin: - log.I.Ln(reflect.TypeOf(on)) + log.T.Ln(reflect.TypeOf(on)) cl.reply(on, b, c) case *response.OnionSkin: - log.I.Ln(reflect.TypeOf(on)) + log.T.Ln(reflect.TypeOf(on)) cl.response(on, b, c) case *session.OnionSkin: - log.I.Ln(reflect.TypeOf(on)) + log.T.Ln(reflect.TypeOf(on)) cl.session(on, b, c) case *token.OnionSkin: - log.I.Ln(reflect.TypeOf(on)) + log.T.Ln(reflect.TypeOf(on)) cl.token(on, b, c) default: log.I.S("unrecognised packet", b) @@ -146,7 +156,13 @@ func (cl *Client) confirm(on *confirm.OnionSkin, b slice.Bytes, // This will be an 8 byte nonce that confirms a message passed, ping and // cipher onions return these, as they are pure forward messages that // send a message one way and the confirmation is the acknowledgement. - log.I.S(on) + // log.I.S(on) + for i := range cl.Confirms { + // log.I.S(cl.Confirms[i].ID, on.ID) + if on.ID == cl.Confirms[i].ID { + cl.Confirms[i].Hook(on) + } + } } func (cl *Client) delay(on *delay.OnionSkin, b slice.Bytes, cur *slice.Cursor) { @@ -167,28 +183,28 @@ func (cl *Client) forward(on *forward.OnionSkin, b slice.Bytes, c *slice.Cursor) if on.AddrPort.String() == cl.Node.AddrPort.String() { // it is for us, we want to unwrap the next // part. - log.I.Ln("processing new message", *c) + log.T.Ln("processing new message", *c) b = append(b[*c:], slice.NoisePad(int(*c))...) cl.Node.Send(b) } else { // we need to forward this message onion. - log.I.Ln("forwarding") + log.T.Ln("forwarding") cl.Send(on.AddrPort, b) } } func (cl *Client) layer(on *layer.OnionSkin, b slice.Bytes, c *slice.Cursor) { // this is probably an encrypted layer for us. - log.I.Ln("decrypting onion skin") + log.T.Ln("decrypting onion skin") // log.I.S(on, b[*c:].ToBytes()) rcv := cl.ReceiveCache.FindCloaked(on.Cloak) if rcv == nil { - log.I.Ln("no matching key found from cloaked key") + log.T.Ln("no matching key found from cloaked key") return } on.Decrypt(rcv.Key, b, c) b = append(b[*c:], slice.NoisePad(int(*c))...) - log.I.S(b.ToBytes()) + log.T.S(b.ToBytes()) cl.Node.Send(b) } @@ -236,6 +252,15 @@ func (cl *Client) token(t *token.OnionSkin, b slice.Bytes, cur *slice.Cursor) { return } +func (cl *Client) RegisterConfirmation(id nonce.ID, hook ConfirmHook) { + cl.Mutex.Lock() + cl.Confirms = append(cl.Confirms, ConfirmCallback{ + ID: id, + Hook: hook, + }) + cl.Mutex.Unlock() +} + func (cl *Client) Cleanup() { // Do cleanup stuff before shutdown. } diff --git a/pkg/client/client_test.go b/pkg/client/client_test.go index 1f1a471a..ac660f59 100644 --- a/pkg/client/client_test.go +++ b/pkg/client/client_test.go @@ -13,11 +13,14 @@ import ( "github.com/Indra-Labs/indra/pkg/slice" "github.com/Indra-Labs/indra/pkg/transport" "github.com/Indra-Labs/indra/pkg/wire" + "github.com/Indra-Labs/indra/pkg/wire/confirm" log2 "github.com/cybriq/proc/pkg/log" + "github.com/cybriq/qu" ) func TestPing(t *testing.T) { log2.CodeLoc = true + // log2.SetLogLevel(log2.Trace) var clients [4]*Client var nodes [4]*node.Node var transports [4]ifc.Transport @@ -69,15 +72,29 @@ func TestPing(t *testing.T) { hop[i] = clients[0].Nodes[i] } os := wire.Ping(pn, clients[0].Node, hop, ks) - log.I.S(os) + // log.I.S(os) + quit := qu.T() + log.I.S("sending ping with ID", os[len(os)-1].(*confirm.OnionSkin)) + clients[0].RegisterConfirmation( + os[len(os)-1].(*confirm.OnionSkin).ID, + func(cf *confirm.OnionSkin) { + log.I.S("received ping confirmation ID", cf) + quit.Q() + }, + ) o := os.Assemble() b := wire.EncodeOnion(o) - // log.I.S(b.ToBytes()) hop[0].Send(b) - time.Sleep(time.Second * 5) + go func() { + time.Sleep(time.Second * 2) + quit.Q() + t.Error("ping got stuck") + }() + <-quit.Wait() for _, v := range clients { v.Shutdown() } + } // diff --git a/version.go b/version.go index 272bbcbe..d7e682be 100644 --- a/version.go +++ b/version.go @@ -10,11 +10,11 @@ var ( // GitRef is the gitref, as in refs/heads/branchname. GitRef = "refs/heads/main" // ParentGitCommit is the commit hash of the parent HEAD. - ParentGitCommit = "ed542f0b9ced648125640f1f8c4f5f4fe55cd677" + ParentGitCommit = "00b39b876b26ec360bd3557c579bb174c36a426b" // BuildTime stores the time when the current binary was built. - BuildTime = "2022-12-29T09:14:38Z" + BuildTime = "2022-12-29T09:56:47Z" // SemVer lists the (latest) git tag on the release. - SemVer = "v0.0.257" + SemVer = "v0.0.258" // PathBase is the path base returned from runtime caller. PathBase = "/home/loki/src/github.com/Indra-Labs/indra/" // Major is the major number from the tag. @@ -22,7 +22,7 @@ var ( // Minor is the minor number from the tag. Minor = 0 // Patch is the patch version number from the tag. - Patch = 257 + Patch = 258 ) // Version returns a pretty printed version information string.