Split everything fully apart
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
package node
|
||||
package client
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
@@ -7,13 +7,17 @@ import (
|
||||
|
||||
"github.com/cybriq/qu"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/indra-labs/indra"
|
||||
"github.com/indra-labs/indra/pkg/ifc"
|
||||
"github.com/indra-labs/indra/pkg/key/cloak"
|
||||
"github.com/indra-labs/indra/pkg/key/prv"
|
||||
"github.com/indra-labs/indra/pkg/key/pub"
|
||||
"github.com/indra-labs/indra/pkg/key/signer"
|
||||
log2 "github.com/indra-labs/indra/pkg/log"
|
||||
"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/traffic"
|
||||
"github.com/indra-labs/indra/pkg/wire/confirm"
|
||||
"github.com/indra-labs/indra/pkg/wire/layer"
|
||||
"github.com/indra-labs/indra/pkg/wire/response"
|
||||
@@ -21,14 +25,19 @@ import (
|
||||
"go.uber.org/atomic"
|
||||
)
|
||||
|
||||
var (
|
||||
log = log2.GetLogger(indra.PathBase)
|
||||
check = log.E.Chk
|
||||
)
|
||||
|
||||
const (
|
||||
ReverseLayerLen = reverse.Len + layer.Len
|
||||
ReverseHeaderLen = 3 * ReverseLayerLen
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
*Node
|
||||
Nodes
|
||||
*node.Node
|
||||
node.Nodes
|
||||
sync.Mutex
|
||||
*confirm.Confirms
|
||||
response.Hooks
|
||||
@@ -37,8 +46,8 @@ type Client struct {
|
||||
qu.C
|
||||
}
|
||||
|
||||
func NewClient(tpt ifc.Transport, hdrPrv *prv.Key, no *Node,
|
||||
nodes Nodes) (c *Client, e error) {
|
||||
func NewClient(tpt ifc.Transport, hdrPrv *prv.Key, no *node.Node,
|
||||
nodes node.Nodes) (c *Client, e error) {
|
||||
|
||||
no.Transport = tpt
|
||||
no.IdentityPrv = hdrPrv
|
||||
@@ -48,7 +57,7 @@ func NewClient(tpt ifc.Transport, hdrPrv *prv.Key, no *Node,
|
||||
return
|
||||
}
|
||||
// Add our first return session.
|
||||
no.AddSession(NewSession(nonce.NewID(), no, 0, nil, nil, 5))
|
||||
no.AddSession(traffic.NewSession(nonce.NewID(), no.Peer, 0, nil, nil, 5))
|
||||
c = &Client{
|
||||
Confirms: confirm.NewConfirms(),
|
||||
Node: no,
|
||||
@@ -82,7 +91,7 @@ func (cl *Client) RegisterConfirmation(hook confirm.Hook,
|
||||
// returns the session as well, though not all users of this function will need
|
||||
// this.
|
||||
func (cl *Client) FindCloaked(clk cloak.PubKey) (hdr *prv.Key,
|
||||
pld *prv.Key, sess *Session, identity bool) {
|
||||
pld *prv.Key, sess *traffic.Session, identity bool) {
|
||||
|
||||
var b cloak.Blinder
|
||||
copy(b[:], clk[:cloak.BlindLen])
|
||||
@@ -95,7 +104,7 @@ func (cl *Client) FindCloaked(clk cloak.PubKey) (hdr *prv.Key,
|
||||
return
|
||||
}
|
||||
var i int
|
||||
cl.Node.IterateSessions(func(s *Session) (stop bool) {
|
||||
cl.Node.IterateSessions(func(s *traffic.Session) (stop bool) {
|
||||
hash = cloak.Cloak(b, s.HeaderBytes)
|
||||
if hash == clk {
|
||||
log.T.F("found cloaked key in session %d", i)
|
||||
@@ -1,4 +1,4 @@
|
||||
package node
|
||||
package client
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@@ -7,9 +7,12 @@ import (
|
||||
"github.com/cybriq/qu"
|
||||
"github.com/indra-labs/indra/pkg/key/prv"
|
||||
"github.com/indra-labs/indra/pkg/nonce"
|
||||
"github.com/indra-labs/indra/pkg/onion"
|
||||
"github.com/indra-labs/indra/pkg/service"
|
||||
"github.com/indra-labs/indra/pkg/sha256"
|
||||
"github.com/indra-labs/indra/pkg/slice"
|
||||
"github.com/indra-labs/indra/pkg/tests"
|
||||
"github.com/indra-labs/indra/pkg/traffic"
|
||||
"github.com/indra-labs/indra/pkg/transport"
|
||||
"github.com/indra-labs/indra/pkg/wire/confirm"
|
||||
"github.com/indra-labs/indra/pkg/wire/session"
|
||||
@@ -28,18 +31,18 @@ func TestPing(t *testing.T) {
|
||||
go v.Start()
|
||||
}
|
||||
conf := nonce.NewID()
|
||||
var circuit Circuit
|
||||
var circuit traffic.Circuit
|
||||
for i := range circuit {
|
||||
circuit[i] = clients[i+1].GetSessionByIndex(1)
|
||||
}
|
||||
os := Ping(conf, clients[0].GetSessionByIndex(0),
|
||||
os := onion.Ping(conf, clients[0].GetSessionByIndex(0),
|
||||
circuit, clients[0].KeySet)
|
||||
quit := qu.T()
|
||||
clients[0].RegisterConfirmation(func(cf nonce.ID) {
|
||||
log.T.S("received ping confirmation ID", cf)
|
||||
quit.Q()
|
||||
}, os[len(os)-1].(*confirm.OnionSkin).ID)
|
||||
b := EncodeOnion(os.Assemble())
|
||||
b := onion.Encode(os.Assemble())
|
||||
log.T.S("sending ping with ID", os[len(os)-1].(*confirm.OnionSkin))
|
||||
clients[0].Send(clients[0].Nodes[0].AddrPort, b)
|
||||
go func() {
|
||||
@@ -66,7 +69,7 @@ func TestSendExit(t *testing.T) {
|
||||
}
|
||||
// set up forwarding port service
|
||||
const port = 3455
|
||||
clients[3].Services = append(clients[3].Services, &Service{
|
||||
clients[3].Services = append(clients[3].Services, &service.Service{
|
||||
Port: port,
|
||||
Transport: transport.NewSim(0),
|
||||
})
|
||||
@@ -74,7 +77,7 @@ func TestSendExit(t *testing.T) {
|
||||
for _, v := range clients {
|
||||
go v.Start()
|
||||
}
|
||||
var circuit Circuit
|
||||
var circuit traffic.Circuit
|
||||
for i := range circuit {
|
||||
circuit[i] = clients[0].GetSessionByIndex(i + 1)
|
||||
}
|
||||
@@ -91,7 +94,7 @@ func TestSendExit(t *testing.T) {
|
||||
t.FailNow()
|
||||
}
|
||||
quit := qu.T()
|
||||
os := SendExit(msg, port, clients[0].GetSessionByIndex(0), circuit,
|
||||
os := onion.SendExit(msg, port, clients[0].GetSessionByIndex(0), circuit,
|
||||
clients[0].KeySet)
|
||||
clients[0].Hooks = clients[0].Hooks.Add(msgHash,
|
||||
func(b slice.Bytes) {
|
||||
@@ -101,7 +104,7 @@ func TestSendExit(t *testing.T) {
|
||||
}
|
||||
quit.Q()
|
||||
})
|
||||
b := EncodeOnion(os.Assemble())
|
||||
b := onion.Encode(os.Assemble())
|
||||
log.T.Ln(clients[0].Node.AddrPort.String())
|
||||
clients[0].Node.Send(b)
|
||||
go func() {
|
||||
@@ -154,17 +157,17 @@ func TestSendKeys(t *testing.T) {
|
||||
clients[i+1].PaymentChan <- pmt[i]
|
||||
}
|
||||
// Send the keys.
|
||||
var circuit Circuit
|
||||
var circuit traffic.Circuit
|
||||
for i := range circuit {
|
||||
circuit[i] = NewSession(pmt[i].ID,
|
||||
clients[i+1].Node, pmt[i].Amount,
|
||||
circuit[i] = traffic.NewSession(pmt[i].ID,
|
||||
clients[i+1].Node.Peer, pmt[i].Amount,
|
||||
sess[i].Header, sess[i].Payload, byte(i))
|
||||
}
|
||||
var hdr, pld [5]*prv.Key
|
||||
for i := range hdr {
|
||||
hdr[i], pld[i] = sess[i].Header, sess[i].Payload
|
||||
}
|
||||
sk := SendKeys(cnf, hdr, pld, clients[0].GetSessionByIndex(0),
|
||||
sk := onion.SendKeys(cnf, hdr, pld, clients[0].GetSessionByIndex(0),
|
||||
circuit, clients[0].KeySet)
|
||||
clients[0].RegisterConfirmation(func(cf nonce.ID) {
|
||||
log.T.S("received payment confirmation ID", cf)
|
||||
@@ -175,7 +178,7 @@ func TestSendKeys(t *testing.T) {
|
||||
}
|
||||
quit.Q()
|
||||
}, cnf)
|
||||
b := EncodeOnion(sk.Assemble())
|
||||
b := onion.Encode(sk.Assemble())
|
||||
clients[0].Send(clients[0].Nodes[0].AddrPort, b)
|
||||
<-quit.Wait()
|
||||
for _, v := range clients {
|
||||
@@ -1,4 +1,4 @@
|
||||
package node
|
||||
package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -8,8 +8,10 @@ import (
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/indra-labs/indra/pkg/ciph"
|
||||
"github.com/indra-labs/indra/pkg/nonce"
|
||||
"github.com/indra-labs/indra/pkg/onion"
|
||||
"github.com/indra-labs/indra/pkg/sha256"
|
||||
"github.com/indra-labs/indra/pkg/slice"
|
||||
"github.com/indra-labs/indra/pkg/traffic"
|
||||
"github.com/indra-labs/indra/pkg/types"
|
||||
"github.com/indra-labs/indra/pkg/wire/balance"
|
||||
"github.com/indra-labs/indra/pkg/wire/confirm"
|
||||
@@ -47,13 +49,13 @@ func (cl *Client) runner() (out bool) {
|
||||
break
|
||||
case b := <-cl.Node.Receive():
|
||||
// process received message
|
||||
var onion types.Onion
|
||||
var on types.Onion
|
||||
var e error
|
||||
c := slice.NewCursor()
|
||||
if onion, e = PeelOnion(b, c); check(e) {
|
||||
if on, e = onion.Peel(b, c); check(e) {
|
||||
break
|
||||
}
|
||||
switch on := onion.(type) {
|
||||
switch on := on.(type) {
|
||||
case *balance.OnionSkin:
|
||||
log.T.C(recLog(on, b, cl))
|
||||
cl.balance(on, b, c)
|
||||
@@ -96,7 +98,7 @@ func (cl *Client) runner() (out bool) {
|
||||
case p := <-cl.PaymentChan:
|
||||
log.T.S("incoming payment", cl.AddrPort.String(), p)
|
||||
topUp := false
|
||||
cl.IterateSessions(func(s *Session) bool {
|
||||
cl.IterateSessions(func(s *traffic.Session) bool {
|
||||
if s.Preimage == p.Preimage {
|
||||
s.AddBytes(p.Amount)
|
||||
topUp = true
|
||||
@@ -134,7 +136,7 @@ func (cl *Client) confirm(on *confirm.OnionSkin,
|
||||
func (cl *Client) balance(on *balance.OnionSkin,
|
||||
b slice.Bytes, c *slice.Cursor) {
|
||||
|
||||
cl.IterateSessions(func(s *Session) bool {
|
||||
cl.IterateSessions(func(s *traffic.Session) bool {
|
||||
if s.ID == on.ID {
|
||||
log.T.F("received balance %x for session %x",
|
||||
on.MilliSatoshi, on.ID)
|
||||
@@ -175,7 +177,7 @@ func (cl *Client) exit(on *exit.OnionSkin, b slice.Bytes,
|
||||
case <-timer.C:
|
||||
}
|
||||
// We need to wrap the result in a message layer.
|
||||
res := EncodeOnion(&response.OnionSkin{
|
||||
res := onion.Encode(&response.OnionSkin{
|
||||
Hash: sha256.Single(on.Bytes),
|
||||
Bytes: result,
|
||||
})
|
||||
@@ -191,7 +193,7 @@ func (cl *Client) forward(on *forward.OnionSkin, b slice.Bytes,
|
||||
// layer.OnionSkin under this which will be unwrapped by the receiver.
|
||||
if on.AddrPort.String() == cl.Node.AddrPort.String() {
|
||||
// it is for us, we want to unwrap the next part.
|
||||
// cl.Node.Send(append(b[*c:], slice.NoisePad(int(*c))...))
|
||||
// cl.Peer.Send(append(b[*c:], slice.NoisePad(int(*c))...))
|
||||
cl.Node.Send(BudgeUp(b, *c))
|
||||
} else {
|
||||
// we need to forward this message onion.
|
||||
@@ -204,7 +206,7 @@ func (cl *Client) getBalance(on *getbalance.OnionSkin,
|
||||
|
||||
var found bool
|
||||
var bal *balance.OnionSkin
|
||||
cl.IterateSessions(func(s *Session) bool {
|
||||
cl.IterateSessions(func(s *traffic.Session) bool {
|
||||
if s.ID == on.ID {
|
||||
bal = &balance.OnionSkin{
|
||||
ID: on.ID,
|
||||
@@ -219,7 +221,7 @@ func (cl *Client) getBalance(on *getbalance.OnionSkin,
|
||||
return
|
||||
}
|
||||
rb := FormatReply(b[*c:c.Inc(ReverseHeaderLen)],
|
||||
EncodeOnion(bal), on.Ciphers, on.Nonces)
|
||||
onion.Encode(bal), on.Ciphers, on.Nonces)
|
||||
cl.Node.Send(rb)
|
||||
}
|
||||
|
||||
@@ -268,12 +270,12 @@ func (cl *Client) reverse(on *reverse.OnionSkin, b slice.Bytes,
|
||||
c *slice.Cursor) {
|
||||
|
||||
var e error
|
||||
var onion types.Onion
|
||||
var on2 types.Onion
|
||||
if on.AddrPort.String() == cl.Node.AddrPort.String() {
|
||||
if onion, e = PeelOnion(b, c); check(e) {
|
||||
if on2, e = onion.Peel(b, c); check(e) {
|
||||
return
|
||||
}
|
||||
switch on1 := onion.(type) {
|
||||
switch on1 := on2.(type) {
|
||||
case *layer.OnionSkin:
|
||||
start := *c - ReverseLayerLen
|
||||
first := *c
|
||||
@@ -338,8 +340,8 @@ func (cl *Client) session(on *session.OnionSkin, b slice.Bytes,
|
||||
// duplicate sessions.
|
||||
cl.DeletePendingPayment(pi.Preimage)
|
||||
log.T.F("Adding session %x\n", pi.ID)
|
||||
cl.AddSession(NewSession(pi.ID,
|
||||
cl.Node, pi.Amount, on.Header, on.Payload, on.Hop))
|
||||
cl.AddSession(traffic.NewSession(pi.ID,
|
||||
cl.Node.Peer, pi.Amount, on.Header, on.Payload, on.Hop))
|
||||
cl.Node.Send(BudgeUp(b, *c))
|
||||
} else {
|
||||
log.T.Ln("dropping session message without payment")
|
||||
@@ -1,4 +1,4 @@
|
||||
package node
|
||||
package client
|
||||
|
||||
import (
|
||||
"math"
|
||||
@@ -6,8 +6,10 @@ import (
|
||||
"github.com/indra-labs/indra/pkg/ifc"
|
||||
"github.com/indra-labs/indra/pkg/key/prv"
|
||||
"github.com/indra-labs/indra/pkg/key/pub"
|
||||
"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/traffic"
|
||||
"github.com/indra-labs/indra/pkg/transport"
|
||||
)
|
||||
|
||||
@@ -16,9 +18,9 @@ func CreateNMockCircuits(inclSessions bool,
|
||||
|
||||
nTotal := 1 + nCircuits*5
|
||||
cl = make([]*Client, nTotal)
|
||||
nodes := make([]*Node, nTotal)
|
||||
nodes := make([]*node.Node, nTotal)
|
||||
transports := make([]ifc.Transport, nTotal)
|
||||
sessions := make(Sessions, nTotal-1)
|
||||
sessions := make(traffic.Sessions, nTotal-1)
|
||||
for i := range transports {
|
||||
transports[i] = transport.NewSim(nTotal)
|
||||
}
|
||||
@@ -29,7 +31,7 @@ func CreateNMockCircuits(inclSessions bool,
|
||||
}
|
||||
idPub := pub.Derive(idPrv)
|
||||
addr := slice.GenerateRandomAddrPortIPv4()
|
||||
nodes[i], _ = New(addr, idPub, idPrv, transports[i])
|
||||
nodes[i], _ = node.New(addr, idPub, idPrv, transports[i])
|
||||
if cl[i], e = NewClient(transports[i], idPrv, nodes[i],
|
||||
nil); check(e) {
|
||||
return
|
||||
@@ -39,8 +41,8 @@ func CreateNMockCircuits(inclSessions bool,
|
||||
if inclSessions {
|
||||
// create a session for all but the first
|
||||
if i > 0 {
|
||||
sessions[i-1] = NewSession(
|
||||
nonce.NewID(), nodes[i],
|
||||
sessions[i-1] = traffic.NewSession(
|
||||
nonce.NewID(), nodes[i].Peer,
|
||||
math.MaxUint64, nil, nil,
|
||||
byte(i/nCircuits-1))
|
||||
// Add session to node, so it will be able to
|
||||
17
pkg/identity/identity.go
Normal file
17
pkg/identity/identity.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package identity
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
|
||||
"github.com/indra-labs/indra/pkg/ifc"
|
||||
"github.com/indra-labs/indra/pkg/key/prv"
|
||||
"github.com/indra-labs/indra/pkg/key/pub"
|
||||
)
|
||||
|
||||
type Peer struct {
|
||||
AddrPort *netip.AddrPort
|
||||
IdentityPub *pub.Key
|
||||
IdentityBytes pub.Bytes
|
||||
IdentityPrv *prv.Key
|
||||
ifc.Transport
|
||||
}
|
||||
@@ -7,11 +7,21 @@ import (
|
||||
"net/netip"
|
||||
"time"
|
||||
|
||||
"github.com/indra-labs/indra"
|
||||
"github.com/indra-labs/indra/pkg/identity"
|
||||
"github.com/indra-labs/indra/pkg/ifc"
|
||||
"github.com/indra-labs/indra/pkg/key/prv"
|
||||
"github.com/indra-labs/indra/pkg/key/pub"
|
||||
log2 "github.com/indra-labs/indra/pkg/log"
|
||||
"github.com/indra-labs/indra/pkg/nonce"
|
||||
"github.com/indra-labs/indra/pkg/service"
|
||||
"github.com/indra-labs/indra/pkg/slice"
|
||||
"github.com/indra-labs/indra/pkg/traffic"
|
||||
)
|
||||
|
||||
var (
|
||||
log = log2.GetLogger(indra.PathBase)
|
||||
check = log.E.Chk
|
||||
)
|
||||
|
||||
// Node is a representation of a messaging counterparty. The netip.AddrPort can
|
||||
@@ -21,15 +31,11 @@ import (
|
||||
// known via the packet sender address.
|
||||
type Node struct {
|
||||
nonce.ID
|
||||
AddrPort *netip.AddrPort
|
||||
IdentityPub *pub.Key
|
||||
IdentityBytes pub.Bytes
|
||||
IdentityPrv *prv.Key
|
||||
PingCount int
|
||||
LastSeen time.Time
|
||||
*Payments
|
||||
Services
|
||||
ifc.Transport
|
||||
*identity.Peer
|
||||
PingCount int
|
||||
LastSeen time.Time
|
||||
*traffic.Payments
|
||||
service.Services
|
||||
}
|
||||
|
||||
// New creates a new Node. netip.AddrPort is optional if the counterparty is not
|
||||
@@ -40,13 +46,15 @@ func New(addr *netip.AddrPort, idPub *pub.Key, idPrv *prv.Key,
|
||||
|
||||
id = nonce.NewID()
|
||||
n = &Node{
|
||||
ID: id,
|
||||
AddrPort: addr,
|
||||
Transport: tpt,
|
||||
IdentityPub: idPub,
|
||||
IdentityBytes: idPub.ToBytes(),
|
||||
IdentityPrv: idPrv,
|
||||
Payments: NewPayments(),
|
||||
ID: id,
|
||||
Peer: &identity.Peer{
|
||||
AddrPort: addr,
|
||||
IdentityPub: idPub,
|
||||
IdentityBytes: idPub.ToBytes(),
|
||||
IdentityPrv: idPrv,
|
||||
Transport: tpt,
|
||||
},
|
||||
Payments: traffic.NewPayments(),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"github.com/indra-labs/indra/pkg/key/ecdh"
|
||||
"github.com/indra-labs/indra/pkg/key/prv"
|
||||
"github.com/indra-labs/indra/pkg/key/pub"
|
||||
"github.com/indra-labs/indra/pkg/nonce"
|
||||
"github.com/indra-labs/indra/pkg/sha256"
|
||||
)
|
||||
|
||||
func GenCiphers(prvs [3]*prv.Key, pubs [3]*pub.Key) (ciphers [3]sha256.Hash) {
|
||||
for i := range prvs {
|
||||
ciphers[2-i] = ecdh.Compute(prvs[i], pubs[i])
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func Gen3Nonces() (n [3]nonce.IV) {
|
||||
for i := range n {
|
||||
n[i] = nonce.New()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GenNonces(count int) (n []nonce.IV) {
|
||||
n = make([]nonce.IV, count)
|
||||
for i := range n {
|
||||
n[i] = nonce.New()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GenPingNonces() (n [6]nonce.IV) {
|
||||
for i := range n {
|
||||
n[i] = nonce.New()
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -1,11 +1,16 @@
|
||||
package node
|
||||
package onion
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/indra-labs/indra"
|
||||
"github.com/indra-labs/indra/pkg/key/ecdh"
|
||||
"github.com/indra-labs/indra/pkg/key/prv"
|
||||
"github.com/indra-labs/indra/pkg/key/pub"
|
||||
log2 "github.com/indra-labs/indra/pkg/log"
|
||||
"github.com/indra-labs/indra/pkg/nonce"
|
||||
"github.com/indra-labs/indra/pkg/sha256"
|
||||
"github.com/indra-labs/indra/pkg/slice"
|
||||
"github.com/indra-labs/indra/pkg/types"
|
||||
"github.com/indra-labs/indra/pkg/wire/confirm"
|
||||
@@ -25,7 +30,7 @@ var (
|
||||
check = log.E.Chk
|
||||
)
|
||||
|
||||
func EncodeOnion(on types.Onion) (b slice.Bytes) {
|
||||
func Encode(on types.Onion) (b slice.Bytes) {
|
||||
b = make(slice.Bytes, on.Len())
|
||||
var sc slice.Cursor
|
||||
c := &sc
|
||||
@@ -33,7 +38,7 @@ func EncodeOnion(on types.Onion) (b slice.Bytes) {
|
||||
return
|
||||
}
|
||||
|
||||
func PeelOnion(b slice.Bytes, c *slice.Cursor) (on types.Onion, e error) {
|
||||
func Peel(b slice.Bytes, c *slice.Cursor) (on types.Onion, e error) {
|
||||
switch b[*c:c.Inc(magicbytes.Len)].String() {
|
||||
case session.MagicString:
|
||||
o := &session.OnionSkin{}
|
||||
@@ -98,3 +103,32 @@ func PeelOnion(b slice.Bytes, c *slice.Cursor) (on types.Onion, e error) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GenCiphers(prvs [3]*prv.Key, pubs [3]*pub.Key) (ciphers [3]sha256.Hash) {
|
||||
for i := range prvs {
|
||||
ciphers[2-i] = ecdh.Compute(prvs[i], pubs[i])
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func Gen3Nonces() (n [3]nonce.IV) {
|
||||
for i := range n {
|
||||
n[i] = nonce.New()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GenNonces(count int) (n []nonce.IV) {
|
||||
n = make([]nonce.IV, count)
|
||||
for i := range n {
|
||||
n[i] = nonce.New()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GenPingNonces() (n [6]nonce.IV) {
|
||||
for i := range n {
|
||||
n[i] = nonce.New()
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package node
|
||||
package onion
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
@@ -31,13 +31,13 @@ func TestOnionSkins_Cipher(t *testing.T) {
|
||||
var e error
|
||||
hdrP, pldP := GetTwoPrvKeys(t)
|
||||
// hdr, pld := pub.Derive(hdrP), pub.Derive(pldP)
|
||||
on := OnionSkins{}.
|
||||
on := Skins{}.
|
||||
Session(hdrP, pldP).
|
||||
Assemble()
|
||||
onb := EncodeOnion(on)
|
||||
onb := Encode(on)
|
||||
c := slice.NewCursor()
|
||||
var onc types.Onion
|
||||
if onc, e = PeelOnion(onb, c); check(e) {
|
||||
if onc, e = Peel(onb, c); check(e) {
|
||||
t.FailNow()
|
||||
}
|
||||
var ci *session.OnionSkin
|
||||
@@ -60,13 +60,13 @@ func TestOnionSkins_Confirmation(t *testing.T) {
|
||||
|
||||
var e error
|
||||
n := nonce.NewID()
|
||||
on := OnionSkins{}.
|
||||
on := Skins{}.
|
||||
Confirmation(n).
|
||||
Assemble()
|
||||
onb := EncodeOnion(on)
|
||||
onb := Encode(on)
|
||||
c := slice.NewCursor()
|
||||
var oncn types.Onion
|
||||
if oncn, e = PeelOnion(onb, c); check(e) {
|
||||
if oncn, e = Peel(onb, c); check(e) {
|
||||
t.FailNow()
|
||||
}
|
||||
var cf *confirm.OnionSkin
|
||||
@@ -85,13 +85,13 @@ func TestOnionSkins_Delay(t *testing.T) {
|
||||
|
||||
var e error
|
||||
del := time.Duration(rand.Uint64())
|
||||
on := OnionSkins{}.
|
||||
on := Skins{}.
|
||||
Delay(del).
|
||||
Assemble()
|
||||
onb := EncodeOnion(on)
|
||||
onb := Encode(on)
|
||||
c := slice.NewCursor()
|
||||
var ond types.Onion
|
||||
if ond, e = PeelOnion(onb, c); check(e) {
|
||||
if ond, e = Peel(onb, c); check(e) {
|
||||
t.FailNow()
|
||||
}
|
||||
var dl *delay.OnionSkin
|
||||
@@ -119,13 +119,13 @@ func TestOnionSkins_Exit(t *testing.T) {
|
||||
}
|
||||
n3 := Gen3Nonces()
|
||||
p := uint16(rand.Uint32())
|
||||
on := OnionSkins{}.
|
||||
on := Skins{}.
|
||||
Exit(p, prvs, pubs, n3, msg).
|
||||
Assemble()
|
||||
onb := EncodeOnion(on)
|
||||
onb := Encode(on)
|
||||
c := slice.NewCursor()
|
||||
var onex types.Onion
|
||||
if onex, e = PeelOnion(onb, c); check(e) {
|
||||
if onex, e = Peel(onb, c); check(e) {
|
||||
t.FailNow()
|
||||
}
|
||||
var ex *exit.OnionSkin
|
||||
@@ -178,13 +178,13 @@ func TestOnionSkins_Forward(t *testing.T) {
|
||||
}
|
||||
port := uint16(rand.Uint32())
|
||||
ap := netip.AddrPortFrom(adr, port)
|
||||
on := OnionSkins{}.
|
||||
on := Skins{}.
|
||||
Forward(&ap).
|
||||
Assemble()
|
||||
onb := EncodeOnion(on)
|
||||
onb := Encode(on)
|
||||
c := slice.NewCursor()
|
||||
var onf types.Onion
|
||||
if onf, e = PeelOnion(onb, c); check(e) {
|
||||
if onf, e = Peel(onb, c); check(e) {
|
||||
t.FailNow()
|
||||
}
|
||||
var cf *forward.OnionSkin
|
||||
@@ -207,14 +207,14 @@ func TestOnionSkins_Layer(t *testing.T) {
|
||||
n1 := nonce.New()
|
||||
prv1, prv2 := GetTwoPrvKeys(t)
|
||||
pub1 := pub.Derive(prv1)
|
||||
on := OnionSkins{}.
|
||||
on := Skins{}.
|
||||
Layer(pub1, prv2, n1).
|
||||
Confirmation(n).
|
||||
Assemble()
|
||||
onb := EncodeOnion(on)
|
||||
onb := Encode(on)
|
||||
c := slice.NewCursor()
|
||||
var onos, onc types.Onion
|
||||
if onos, e = PeelOnion(onb, c); check(e) {
|
||||
if onos, e = Peel(onb, c); check(e) {
|
||||
t.Error(e)
|
||||
t.FailNow()
|
||||
}
|
||||
@@ -226,7 +226,7 @@ func TestOnionSkins_Layer(t *testing.T) {
|
||||
}
|
||||
os.Decrypt(prv1, onb, c)
|
||||
// unwrap the confirmation
|
||||
if onc, e = PeelOnion(onb, c); check(e) {
|
||||
if onc, e = Peel(onb, c); check(e) {
|
||||
t.Error(e)
|
||||
t.FailNow()
|
||||
}
|
||||
@@ -262,13 +262,13 @@ func TestOnionSkins_Reply(t *testing.T) {
|
||||
}
|
||||
port := uint16(rand.Uint32())
|
||||
ap := netip.AddrPortFrom(adr, port)
|
||||
on := OnionSkins{}.
|
||||
on := Skins{}.
|
||||
Reverse(&ap).
|
||||
Assemble()
|
||||
onb := EncodeOnion(on)
|
||||
onb := Encode(on)
|
||||
c := slice.NewCursor()
|
||||
var onf types.Onion
|
||||
if onf, e = PeelOnion(onb, c); check(e) {
|
||||
if onf, e = Peel(onb, c); check(e) {
|
||||
t.FailNow()
|
||||
}
|
||||
var cf *reverse.OnionSkin
|
||||
@@ -293,13 +293,13 @@ func TestOnionSkins_Response(t *testing.T) {
|
||||
t.Error(e)
|
||||
t.FailNow()
|
||||
}
|
||||
on := OnionSkins{}.
|
||||
on := Skins{}.
|
||||
Response(hash, msg).
|
||||
Assemble()
|
||||
onb := EncodeOnion(on)
|
||||
onb := Encode(on)
|
||||
c := slice.NewCursor()
|
||||
var onex types.Onion
|
||||
if onex, e = PeelOnion(onb, c); check(e) {
|
||||
if onex, e = Peel(onb, c); check(e) {
|
||||
t.FailNow()
|
||||
}
|
||||
ex := &response.OnionSkin{}
|
||||
@@ -321,13 +321,13 @@ func TestOnionSkins_Token(t *testing.T) {
|
||||
var e error
|
||||
ni := nonce.NewID()
|
||||
n := sha256.Single(ni[:])
|
||||
on := OnionSkins{}.
|
||||
on := Skins{}.
|
||||
Token(n).
|
||||
Assemble()
|
||||
onb := EncodeOnion(on)
|
||||
onb := Encode(on)
|
||||
c := slice.NewCursor()
|
||||
var oncn types.Onion
|
||||
if oncn, e = PeelOnion(onb, c); check(e) {
|
||||
if oncn, e = Peel(onb, c); check(e) {
|
||||
t.FailNow()
|
||||
}
|
||||
var cf *token.OnionSkin
|
||||
@@ -1,4 +1,4 @@
|
||||
package node
|
||||
package onion
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/indra-labs/indra/pkg/nonce"
|
||||
"github.com/indra-labs/indra/pkg/sha256"
|
||||
"github.com/indra-labs/indra/pkg/slice"
|
||||
"github.com/indra-labs/indra/pkg/traffic"
|
||||
"github.com/indra-labs/indra/pkg/types"
|
||||
"github.com/indra-labs/indra/pkg/wire/balance"
|
||||
"github.com/indra-labs/indra/pkg/wire/confirm"
|
||||
@@ -25,36 +26,36 @@ import (
|
||||
"github.com/indra-labs/indra/pkg/wire/token"
|
||||
)
|
||||
|
||||
type OnionSkins []types.Onion
|
||||
type Skins []types.Onion
|
||||
|
||||
var os = &noop.OnionSkin{}
|
||||
|
||||
func (o OnionSkins) ForwardLayer(s *Session, k *prv.Key,
|
||||
n nonce.IV) OnionSkins {
|
||||
func (o Skins) ForwardLayer(s *traffic.Session, k *prv.Key,
|
||||
n nonce.IV) Skins {
|
||||
|
||||
return o.Forward(s.AddrPort).Layer(s.HeaderPub, k, n)
|
||||
return o.Forward(s.Peer.AddrPort).Layer(s.HeaderPub, k, n)
|
||||
}
|
||||
|
||||
func (o OnionSkins) ReverseLayer(s *Session, k *prv.Key,
|
||||
n nonce.IV) OnionSkins {
|
||||
func (o Skins) ReverseLayer(s *traffic.Session, k *prv.Key,
|
||||
n nonce.IV) Skins {
|
||||
|
||||
return o.Reverse(s.AddrPort).Layer(s.HeaderPub, k, n)
|
||||
return o.Reverse(s.Peer.AddrPort).Layer(s.HeaderPub, k, n)
|
||||
}
|
||||
|
||||
func (o OnionSkins) ForwardSession(s *Session,
|
||||
k *prv.Key, n nonce.IV, hdr, pld *prv.Key) OnionSkins {
|
||||
func (o Skins) ForwardSession(s *traffic.Session,
|
||||
k *prv.Key, n nonce.IV, hdr, pld *prv.Key) Skins {
|
||||
|
||||
if hdr == nil || pld == nil {
|
||||
return o.Forward(s.AddrPort).Layer(s.HeaderPub, k, n)
|
||||
return o.Forward(s.Peer.AddrPort).Layer(s.HeaderPub, k, n)
|
||||
} else {
|
||||
return o.Forward(s.AddrPort).
|
||||
Layer(s.IdentityPub, k, n).
|
||||
return o.Forward(s.Peer.AddrPort).
|
||||
Layer(s.Peer.IdentityPub, k, n).
|
||||
Session(hdr, pld)
|
||||
}
|
||||
}
|
||||
|
||||
func (o OnionSkins) Balance(id nonce.ID,
|
||||
amt lnwire.MilliSatoshi) OnionSkins {
|
||||
func (o Skins) Balance(id nonce.ID,
|
||||
amt lnwire.MilliSatoshi) Skins {
|
||||
|
||||
return append(o, &balance.OnionSkin{
|
||||
ID: id,
|
||||
@@ -62,16 +63,16 @@ func (o OnionSkins) Balance(id nonce.ID,
|
||||
})
|
||||
}
|
||||
|
||||
func (o OnionSkins) Confirmation(id nonce.ID) OnionSkins {
|
||||
func (o Skins) Confirmation(id nonce.ID) Skins {
|
||||
return append(o, &confirm.OnionSkin{ID: id})
|
||||
}
|
||||
|
||||
func (o OnionSkins) Delay(d time.Duration) OnionSkins {
|
||||
func (o Skins) Delay(d time.Duration) Skins {
|
||||
return append(o, &delay.OnionSkin{Duration: d, Onion: os})
|
||||
}
|
||||
|
||||
func (o OnionSkins) Exit(port uint16, prvs [3]*prv.Key, pubs [3]*pub.Key,
|
||||
nonces [3]nonce.IV, payload slice.Bytes) OnionSkins {
|
||||
func (o Skins) Exit(port uint16, prvs [3]*prv.Key, pubs [3]*pub.Key,
|
||||
nonces [3]nonce.IV, payload slice.Bytes) Skins {
|
||||
|
||||
return append(o, &exit.OnionSkin{
|
||||
Port: port,
|
||||
@@ -82,7 +83,7 @@ func (o OnionSkins) Exit(port uint16, prvs [3]*prv.Key, pubs [3]*pub.Key,
|
||||
})
|
||||
}
|
||||
|
||||
func (o OnionSkins) Forward(addr *netip.AddrPort) OnionSkins {
|
||||
func (o Skins) Forward(addr *netip.AddrPort) Skins {
|
||||
return append(o,
|
||||
&forward.OnionSkin{
|
||||
AddrPort: addr,
|
||||
@@ -90,8 +91,8 @@ func (o OnionSkins) Forward(addr *netip.AddrPort) OnionSkins {
|
||||
})
|
||||
}
|
||||
|
||||
func (o OnionSkins) GetBalance(id nonce.ID, prvs [3]*prv.Key,
|
||||
pubs [3]*pub.Key, nonces [3]nonce.IV) OnionSkins {
|
||||
func (o Skins) GetBalance(id nonce.ID, prvs [3]*prv.Key,
|
||||
pubs [3]*pub.Key, nonces [3]nonce.IV) Skins {
|
||||
|
||||
return append(o, &getbalance.OnionSkin{
|
||||
ID: id,
|
||||
@@ -101,8 +102,8 @@ func (o OnionSkins) GetBalance(id nonce.ID, prvs [3]*prv.Key,
|
||||
})
|
||||
}
|
||||
|
||||
func (o OnionSkins) Layer(to *pub.Key, from *prv.Key,
|
||||
n nonce.IV) OnionSkins {
|
||||
func (o Skins) Layer(to *pub.Key, from *prv.Key,
|
||||
n nonce.IV) Skins {
|
||||
|
||||
return append(o, &layer.OnionSkin{
|
||||
To: to,
|
||||
@@ -112,16 +113,16 @@ func (o OnionSkins) Layer(to *pub.Key, from *prv.Key,
|
||||
})
|
||||
}
|
||||
|
||||
func (o OnionSkins) Reverse(ip *netip.AddrPort) OnionSkins {
|
||||
func (o Skins) Reverse(ip *netip.AddrPort) Skins {
|
||||
return append(o, &reverse.OnionSkin{AddrPort: ip, Onion: os})
|
||||
}
|
||||
|
||||
func (o OnionSkins) Response(hash sha256.Hash, res slice.Bytes) OnionSkins {
|
||||
func (o Skins) Response(hash sha256.Hash, res slice.Bytes) Skins {
|
||||
rs := response.OnionSkin{Hash: hash, Bytes: res}
|
||||
return append(o, &rs)
|
||||
}
|
||||
|
||||
func (o OnionSkins) Session(hdr, pld *prv.Key) OnionSkins {
|
||||
func (o Skins) Session(hdr, pld *prv.Key) Skins {
|
||||
// SendKeys can apply to from 1 to 5 nodes, if either key is nil then
|
||||
// this layer just doesn't get added in the serialization process.
|
||||
if hdr == nil || pld == nil {
|
||||
@@ -134,7 +135,7 @@ func (o OnionSkins) Session(hdr, pld *prv.Key) OnionSkins {
|
||||
})
|
||||
}
|
||||
|
||||
func (o OnionSkins) Token(tok sha256.Hash) OnionSkins {
|
||||
func (o Skins) Token(tok sha256.Hash) Skins {
|
||||
return append(o, (*token.OnionSkin)(&tok))
|
||||
}
|
||||
|
||||
@@ -142,7 +143,7 @@ func (o OnionSkins) Token(tok sha256.Hash) OnionSkins {
|
||||
// contains the second, second contains the third, and so on, and then returns
|
||||
// the first onion, on which you can then call Encode and generate the wire
|
||||
// message form of the onion.
|
||||
func (o OnionSkins) Assemble() (on types.Onion) {
|
||||
func (o Skins) Assemble() (on types.Onion) {
|
||||
// First item is the outer layer.
|
||||
on = o[0]
|
||||
// Iterate through the remaining layers.
|
||||
@@ -1,4 +1,4 @@
|
||||
package node
|
||||
package onion
|
||||
|
||||
import (
|
||||
"github.com/indra-labs/indra/pkg/key/prv"
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/indra-labs/indra/pkg/key/signer"
|
||||
"github.com/indra-labs/indra/pkg/nonce"
|
||||
"github.com/indra-labs/indra/pkg/slice"
|
||||
"github.com/indra-labs/indra/pkg/traffic"
|
||||
)
|
||||
|
||||
// Ping is a message which checks the liveness of relays by ensuring they are
|
||||
@@ -16,11 +17,11 @@ import (
|
||||
// an increment of their liveness score. By using this scheme, when nodes are
|
||||
// offline their scores will fall to zero after a time whereas live nodes will
|
||||
// have steadily increasing scores from successful pings.
|
||||
func Ping(id nonce.ID, client *Session, s Circuit,
|
||||
ks *signer.KeySet) OnionSkins {
|
||||
func Ping(id nonce.ID, client *traffic.Session, s traffic.Circuit,
|
||||
ks *signer.KeySet) Skins {
|
||||
|
||||
n := GenPingNonces()
|
||||
return OnionSkins{}.
|
||||
return Skins{}.
|
||||
ForwardLayer(s[0], ks.Next(), n[0]).
|
||||
ForwardLayer(s[1], ks.Next(), n[1]).
|
||||
ForwardLayer(s[2], ks.Next(), n[2]).
|
||||
@@ -48,7 +49,7 @@ func Ping(id nonce.ID, client *Session, s Circuit,
|
||||
// their section at the top, moves the next layer header to the top and pads the
|
||||
// remainder with noise, so it always looks like the first hop.
|
||||
func SendExit(payload slice.Bytes, port uint16,
|
||||
client *Session, s Circuit, ks *signer.KeySet) OnionSkins {
|
||||
client *traffic.Session, s traffic.Circuit, ks *signer.KeySet) Skins {
|
||||
|
||||
var prvs [3]*prv.Key
|
||||
for i := range prvs {
|
||||
@@ -61,7 +62,7 @@ func SendExit(payload slice.Bytes, port uint16,
|
||||
pubs[0] = s[3].PayloadPub
|
||||
pubs[1] = s[4].PayloadPub
|
||||
pubs[2] = client.PayloadPub
|
||||
return OnionSkins{}.
|
||||
return Skins{}.
|
||||
ForwardLayer(s[0], ks.Next(), n[0]).
|
||||
ForwardLayer(s[1], ks.Next(), n[1]).
|
||||
ForwardLayer(s[2], ks.Next(), n[2]).
|
||||
@@ -94,10 +95,10 @@ func SendExit(payload slice.Bytes, port uint16,
|
||||
// set of sessions. This is by way of indicating to not use the IdentityPub but
|
||||
// the HeaderPub instead. Not allowing free relay at all prevents spam attacks.
|
||||
func SendKeys(id nonce.ID, hdr, pld [5]*prv.Key,
|
||||
client *Session, hop Circuit, ks *signer.KeySet) OnionSkins {
|
||||
client *traffic.Session, hop traffic.Circuit, ks *signer.KeySet) Skins {
|
||||
|
||||
n := GenNonces(6)
|
||||
return OnionSkins{}.
|
||||
return Skins{}.
|
||||
ForwardSession(hop[0], ks.Next(), n[0], hdr[0], pld[0]).
|
||||
ForwardSession(hop[1], ks.Next(), n[1], hdr[1], pld[1]).
|
||||
ForwardSession(hop[2], ks.Next(), n[2], hdr[2], pld[2]).
|
||||
@@ -112,8 +113,8 @@ func SendKeys(id nonce.ID, hdr, pld [5]*prv.Key,
|
||||
// hops until the client.
|
||||
//
|
||||
// The third returns Session should be the client's return session, index 0.
|
||||
func GetBalance(s Circuit, target int,
|
||||
returns [3]*Session, ks *signer.KeySet) (o OnionSkins) {
|
||||
func GetBalance(s traffic.Circuit, target int,
|
||||
returns [3]*traffic.Session, ks *signer.KeySet) (o Skins) {
|
||||
|
||||
n := GenNonces(target + 1 + 3)
|
||||
var returnNonces [3]nonce.IV
|
||||
@@ -1,4 +1,4 @@
|
||||
package node
|
||||
package service
|
||||
|
||||
import (
|
||||
"github.com/indra-labs/indra/pkg/ifc"
|
||||
@@ -1,22 +1,30 @@
|
||||
package node
|
||||
package traffic
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/indra-labs/indra"
|
||||
"github.com/indra-labs/indra/pkg/identity"
|
||||
"github.com/indra-labs/indra/pkg/key/prv"
|
||||
"github.com/indra-labs/indra/pkg/key/pub"
|
||||
"github.com/indra-labs/indra/pkg/lnd/lnwire"
|
||||
log2 "github.com/indra-labs/indra/pkg/log"
|
||||
"github.com/indra-labs/indra/pkg/nonce"
|
||||
"github.com/indra-labs/indra/pkg/sha256"
|
||||
"github.com/indra-labs/indra/pkg/wire/session"
|
||||
)
|
||||
|
||||
var (
|
||||
log = log2.GetLogger(indra.PathBase)
|
||||
check = log.E.Chk
|
||||
)
|
||||
|
||||
// A Session keeps track of a connection session. It specifically maintains the
|
||||
// account of available bandwidth allocation before it needs to be recharged
|
||||
// with new credit, and the current state of the encryption.
|
||||
type Session struct {
|
||||
nonce.ID
|
||||
*Node
|
||||
*identity.Peer
|
||||
Remaining lnwire.MilliSatoshi
|
||||
HeaderPrv, PayloadPrv *prv.Key
|
||||
HeaderPub, PayloadPub *pub.Key
|
||||
@@ -31,7 +39,7 @@ type Session struct {
|
||||
// allocation.
|
||||
func NewSession(
|
||||
id nonce.ID,
|
||||
node *Node,
|
||||
node *identity.Peer,
|
||||
rem lnwire.MilliSatoshi,
|
||||
hdrPrv *prv.Key,
|
||||
pldPrv *prv.Key,
|
||||
@@ -50,7 +58,7 @@ func NewSession(
|
||||
h, p := hdrPrv.ToBytes(), pldPrv.ToBytes()
|
||||
s = &Session{
|
||||
ID: id,
|
||||
Node: node,
|
||||
Peer: node,
|
||||
Remaining: rem,
|
||||
HeaderPub: hdrPub,
|
||||
HeaderBytes: hdrPub.ToBytes(),
|
||||
Reference in New Issue
Block a user