Changed forward and reply to use netip.AddrPort

This commit is contained in:
David Vennik
2022-12-24 14:07:35 +00:00
parent c263f75115
commit 548fda244e
9 changed files with 213 additions and 58 deletions

View File

@@ -5,6 +5,7 @@ package node
import (
"fmt"
"net"
"net/netip"
"github.com/Indra-Labs/indra"
"github.com/Indra-Labs/indra/pkg/ifc"
@@ -24,18 +25,18 @@ var (
// except when the net.IP is known via the packet sender address.
type Node struct {
nonce.ID
net.IP
netip.AddrPort
HeaderKey, PayloadKey *pub.Key
ifc.Transport
}
// New creates a new Node. net.IP is optional if the counterparty is not in
// direct connection.
func New(ip net.IP, fwd, rtn *pub.Key, tpt ifc.Transport) (n *Node, id nonce.ID) {
func New(ip netip.AddrPort, fwd, rtn *pub.Key, tpt ifc.Transport) (n *Node, id nonce.ID) {
id = nonce.NewID()
n = &Node{
ID: id,
IP: ip,
AddrPort: ip,
Transport: tpt,
HeaderKey: fwd,
PayloadKey: rtn,
@@ -69,9 +70,9 @@ func (n Nodes) FindByID(i nonce.ID) (no *Node) {
}
// FindByIP searches for a Node by net.IP.
func (n Nodes) FindByIP(id net.IP) (no *Node) {
func (n Nodes) FindByIP(id netip.AddrPort) (no *Node) {
for _, nn := range n {
if nn.IP.String() == id.String() {
if nn.AddrPort.String() == id.String() {
no = nn
break
}
@@ -89,7 +90,7 @@ func (n Nodes) DeleteByID(ii nonce.ID) (nn Nodes, e error) {
break
}
}
return
return n, e
}
// DeleteByIP deletes a node identified by a net.IP.
@@ -97,7 +98,7 @@ func (n Nodes) DeleteByIP(ip net.IP) (nn Nodes, e error) {
e = fmt.Errorf("node with ip %v not found", ip)
nn = n
for i := range n {
if n[i].IP.String() == ip.String() {
if n[i].AddrPort.String() == ip.String() {
nn = append(n[:i], n[i+1:]...)
e = nil
break

View File

@@ -6,6 +6,7 @@ import (
"github.com/Indra-Labs/indra/pkg/types"
"github.com/Indra-Labs/indra/pkg/wire/cipher"
"github.com/Indra-Labs/indra/pkg/wire/confirmation"
"github.com/Indra-Labs/indra/pkg/wire/delay"
"github.com/Indra-Labs/indra/pkg/wire/exit"
"github.com/Indra-Labs/indra/pkg/wire/forward"
"github.com/Indra-Labs/indra/pkg/wire/magicbytes"
@@ -45,6 +46,12 @@ func PeelOnion(b slice.Bytes, c *slice.Cursor) (on types.Onion, e error) {
return
}
on = &o
case delay.MagicString:
var o delay.OnionSkin
if e = o.Decode(b, c); check(e) {
return
}
on = &o
case exit.MagicString:
var o exit.OnionSkin
if e = o.Decode(b, c); check(e) {

View File

@@ -2,7 +2,11 @@ package wire
import (
"math/rand"
"net"
"net/netip"
"reflect"
"testing"
"time"
"github.com/Indra-Labs/indra/pkg/key/prv"
"github.com/Indra-Labs/indra/pkg/key/pub"
@@ -13,7 +17,9 @@ import (
"github.com/Indra-Labs/indra/pkg/types"
"github.com/Indra-Labs/indra/pkg/wire/cipher"
"github.com/Indra-Labs/indra/pkg/wire/confirmation"
"github.com/Indra-Labs/indra/pkg/wire/delay"
"github.com/Indra-Labs/indra/pkg/wire/exit"
"github.com/Indra-Labs/indra/pkg/wire/forward"
log2 "github.com/cybriq/proc/pkg/log"
)
@@ -22,14 +28,11 @@ func TestOnionSkins_Cipher(t *testing.T) {
var e error
hdrP, pldP := GetTwoPrvKeys(t)
hdr, pld := pub.Derive(hdrP), pub.Derive(pldP)
// n := nonce.NewID()
on := OnionSkins{}.
Cipher(hdr, pld).
// Confirmation(n).
Assemble()
onb := EncodeOnion(on)
var sc slice.Cursor
c := &sc
c := slice.NewCursor()
var onc types.Onion
if onc, e = PeelOnion(onb, c); check(e) {
t.FailNow()
@@ -58,8 +61,7 @@ func TestOnionSkins_Confirmation(t *testing.T) {
Confirmation(n).
Assemble()
onb := EncodeOnion(on)
var sc slice.Cursor
c := &sc
c := slice.NewCursor()
var oncn types.Onion
if oncn, e = PeelOnion(onb, c); check(e) {
t.FailNow()
@@ -75,6 +77,30 @@ func TestOnionSkins_Confirmation(t *testing.T) {
t.FailNow()
}
}
func TestOnionSkins_Delay(t *testing.T) {
log2.CodeLoc = true
var e error
del := time.Duration(rand.Uint64())
on := OnionSkins{}.
Delay(del).
Assemble()
onb := EncodeOnion(on)
c := slice.NewCursor()
var ond types.Onion
if ond, e = PeelOnion(onb, c); check(e) {
t.FailNow()
}
var dl *delay.OnionSkin
var ok bool
if dl, ok = ond.(*delay.OnionSkin); !ok {
t.Error("did not unwrap expected type")
t.FailNow()
}
if dl.Duration != del {
t.Error("delay duration did not unwrap correctly")
t.FailNow()
}
}
func TestOnionSkins_Exit(t *testing.T) {
log2.CodeLoc = true
@@ -121,7 +147,46 @@ func TestOnionSkins_Exit(t *testing.T) {
}
func TestOnionSkins_Forward(t *testing.T) {
log2.CodeLoc = true
var e error
ipSizes := []int{net.IPv4len, net.IPv6len}
for i := range ipSizes {
n := nonce.New()
ip := net.IP(n[:ipSizes[i]])
var adr netip.Addr
if ipSizes[i] == net.IPv4len {
ip = ip.To4()
}
if ipSizes[i] == net.IPv6len {
ip = ip.To16()
}
var ok bool
if adr, ok = netip.AddrFromSlice(ip); !ok {
t.Error("unable to get netip.Addr")
t.FailNow()
}
port := uint16(rand.Uint32())
ap := netip.AddrPortFrom(adr, port)
on := OnionSkins{}.
Forward(ap).
Assemble()
onb := EncodeOnion(on)
c := slice.NewCursor()
var onf types.Onion
if onf, e = PeelOnion(onb, c); check(e) {
t.FailNow()
}
var cf *forward.OnionSkin
if cf, ok = onf.(*forward.OnionSkin); !ok {
t.Error("did not unwrap expected type", reflect.TypeOf(onf))
t.FailNow()
}
_ = cf
// if !cf.IP.Equal(ip) {
// t.Error("forward IP did not unwrap correctly")
// t.FailNow()
// }
}
}
func TestOnionSkins_Message(t *testing.T) {

46
pkg/wire/delay/delay.go Normal file
View File

@@ -0,0 +1,46 @@
package delay
import (
"time"
"github.com/Indra-Labs/indra"
"github.com/Indra-Labs/indra/pkg/slice"
"github.com/Indra-Labs/indra/pkg/types"
"github.com/Indra-Labs/indra/pkg/wire/magicbytes"
log2 "github.com/cybriq/proc/pkg/log"
)
var (
log = log2.GetLogger(indra.PathBase)
check = log.E.Chk
MagicString = "dl"
Magic = slice.Bytes(MagicString)
MinLen = magicbytes.Len + slice.Uint64Len
_ types.Onion = &OnionSkin{}
)
// A OnionSkin is a 32 byte value.
type OnionSkin struct {
time.Duration
types.Onion
}
func (x *OnionSkin) Inner() types.Onion { return nil }
func (x *OnionSkin) Insert(_ types.Onion) {}
func (x *OnionSkin) Len() int { return MinLen }
func (x *OnionSkin) Encode(b slice.Bytes, c *slice.Cursor) {
copy(b[*c:c.Inc(magicbytes.Len)], Magic)
slice.EncodeUint64(b[*c:c.Inc(slice.Uint64Len)], uint64(x.Duration))
x.Onion.Encode(b, c)
}
func (x *OnionSkin) Decode(b slice.Bytes, c *slice.Cursor) (e error) {
if len(b[*c:]) < MinLen-magicbytes.Len {
return magicbytes.TooShort(len(b[*c:]), MinLen-magicbytes.Len,
string(Magic))
}
x.Duration = time.Duration(
slice.DecodeUint64(b[*c:c.Inc(slice.Uint64Len)]))
return
}

View File

@@ -2,6 +2,7 @@ package forward
import (
"net"
"net/netip"
"github.com/Indra-Labs/indra"
"github.com/Indra-Labs/indra/pkg/slice"
@@ -21,28 +22,41 @@ var (
// OnionSkin forward is just an IP address and a wrapper for another message.
type OnionSkin struct {
net.IP
netip.AddrPort
types.Onion
}
func (x *OnionSkin) Inner() types.Onion { return x.Onion }
func (x *OnionSkin) Insert(o types.Onion) { x.Onion = o }
func (x *OnionSkin) Len() int {
return magicbytes.Len + len(x.IP) + 1 + x.Onion.Len()
var ap []byte
var e error
if ap, e = x.AddrPort.MarshalBinary(); check(e) {
return -1
}
return magicbytes.Len + 1 + len(ap) + x.Onion.Len()
}
func (x *OnionSkin) Encode(b slice.Bytes, c *slice.Cursor) {
copy(b[*c:c.Inc(magicbytes.Len)], Magic)
b[*c] = byte(len(x.IP))
copy(b[c.Inc(1):c.Inc(len(x.IP))], x.IP)
var ap []byte
var e error
if ap, e = x.AddrPort.MarshalBinary(); check(e) {
return
}
b[*c] = byte(len(ap))
x.Onion.Encode(b, c)
}
func (x *OnionSkin) Decode(b slice.Bytes, c *slice.Cursor) (e error) {
if len(b[*c:]) < MinLen {
return magicbytes.TooShort(len(b[*c:]), MinLen, string(Magic))
if len(b[*c:]) < MinLen-magicbytes.Len {
return magicbytes.TooShort(len(b[*c:]), MinLen-magicbytes.Len, string(Magic))
}
apLen := b[*c]
apBytes := b[c.Inc(1):c.Inc(int(apLen))]
if e = x.AddrPort.UnmarshalBinary(apBytes); check(e) {
return
}
ipLen := b[*c]
x.IP = net.IP(b[c.Inc(1):c.Inc(int(ipLen))])
return
}

View File

@@ -1,7 +1,8 @@
package wire
import (
"net"
"net/netip"
"time"
"github.com/Indra-Labs/indra/pkg/key/address"
"github.com/Indra-Labs/indra/pkg/key/ecdh"
@@ -13,6 +14,7 @@ import (
"github.com/Indra-Labs/indra/pkg/types"
"github.com/Indra-Labs/indra/pkg/wire/cipher"
"github.com/Indra-Labs/indra/pkg/wire/confirmation"
"github.com/Indra-Labs/indra/pkg/wire/delay"
"github.com/Indra-Labs/indra/pkg/wire/exit"
"github.com/Indra-Labs/indra/pkg/wire/forward"
"github.com/Indra-Labs/indra/pkg/wire/message"
@@ -40,10 +42,16 @@ func (o OnionSkins) Cipher(hdr, pld *pub.Key) OnionSkins {
Onion: &noop.OnionSkin{},
})
}
func (o OnionSkins) Confirmation(id nonce.ID) OnionSkins {
return append(o, &confirmation.OnionSkin{ID: id})
}
func (o OnionSkins) Delay(d time.Duration) OnionSkins {
return append(o, &delay.OnionSkin{Duration: d,
Onion: &noop.OnionSkin{}})
}
func (o OnionSkins) Exit(port uint16, prvs [3]*prv.Key, pubs [3]*pub.Key,
payload slice.Bytes) OnionSkins {
@@ -54,8 +62,8 @@ func (o OnionSkins) Exit(port uint16, prvs [3]*prv.Key, pubs [3]*pub.Key,
Onion: &noop.OnionSkin{},
})
}
func (o OnionSkins) Forward(ip net.IP) OnionSkins {
return append(o, &forward.OnionSkin{IP: ip, Onion: &noop.OnionSkin{}})
func (o OnionSkins) Forward(addr netip.AddrPort) OnionSkins {
return append(o, &forward.OnionSkin{AddrPort: addr, Onion: &noop.OnionSkin{}})
}
func (o OnionSkins) Message(to *address.Sender, from *prv.Key) OnionSkins {
return append(o, &message.OnionSkin{
@@ -71,8 +79,8 @@ func (o OnionSkins) Purchase(nBytes uint64, ciphers [3]sha256.Hash) OnionSkins {
Onion: &noop.OnionSkin{},
})
}
func (o OnionSkins) Reply(ip net.IP) OnionSkins {
return append(o, &reply.OnionSkin{IP: ip, Onion: &noop.OnionSkin{}})
func (o OnionSkins) Reply(ip netip.AddrPort) OnionSkins {
return append(o, &reply.OnionSkin{AddrPort: ip, Onion: &noop.OnionSkin{}})
}
func (o OnionSkins) Response(res slice.Bytes) OnionSkins {
return append(o, response.OnionSkin(res))

View File

@@ -28,11 +28,11 @@ func Ping(id nonce.ID, client node.Node, hop [3]node.Node,
return OnionSkins{}.
Message(address.FromPubKey(hop[0].HeaderKey), set.Next()).
Forward(hop[1].IP).
Forward(hop[1].AddrPort).
Message(address.FromPubKey(hop[1].HeaderKey), set.Next()).
Forward(hop[2].IP).
Forward(hop[2].AddrPort).
Message(address.FromPubKey(hop[2].HeaderKey), set.Next()).
Forward(client.IP).
Forward(client.AddrPort).
Message(address.FromPubKey(client.HeaderKey), set.Next()).
Confirmation(id).
Assemble()
@@ -56,16 +56,16 @@ func SendKeys(id nonce.ID, hdr, pld *pub.Key,
return OnionSkins{}.
Message(address.FromPubKey(hop[0].HeaderKey), set.Next()).
Forward(hop[1].IP).
Forward(hop[1].AddrPort).
Message(address.FromPubKey(hop[1].HeaderKey), set.Next()).
Forward(hop[2].IP).
Forward(hop[2].AddrPort).
Message(address.FromPubKey(hop[2].HeaderKey), set.Next()).
Cipher(hdr, pld).
Forward(hop[3].IP).
Forward(hop[3].AddrPort).
Message(address.FromPubKey(hop[3].HeaderKey), set.Next()).
Forward(hop[4].IP).
Forward(hop[4].AddrPort).
Message(address.FromPubKey(hop[4].HeaderKey), set.Next()).
Forward(client.IP).
Forward(client.AddrPort).
Message(address.FromPubKey(client.HeaderKey), set.Next()).
Confirmation(id).
Assemble()
@@ -105,16 +105,16 @@ func SendPurchase(nBytes uint64, client node.Node,
return OnionSkins{}.
Message(address.FromPubKey(hop[0].HeaderKey), set.Next()).
Forward(hop[1].IP).
Forward(hop[1].AddrPort).
Message(address.FromPubKey(hop[1].HeaderKey), set.Next()).
Forward(hop[2].IP).
Forward(hop[2].AddrPort).
Message(address.FromPubKey(hop[2].HeaderKey), set.Next()).
Purchase(nBytes, ciphers).
Reply(hop[3].IP).
Reply(hop[3].AddrPort).
Message(address.FromPubKey(hop[3].HeaderKey), rtns[0]).
Reply(hop[4].IP).
Reply(hop[4].AddrPort).
Message(address.FromPubKey(hop[4].HeaderKey), rtns[1]).
Reply(client.IP).
Reply(client.AddrPort).
Message(address.FromPubKey(client.HeaderKey), rtns[2]).
Assemble()
}
@@ -155,16 +155,16 @@ func SendExit(payload slice.Bytes, port uint16, client node.Node,
pubs[2] = hop[3].PayloadKey
return OnionSkins{}.
Message(address.FromPubKey(hop[0].HeaderKey), set.Next()).
Forward(hop[1].IP).
Forward(hop[1].AddrPort).
Message(address.FromPubKey(hop[1].HeaderKey), set.Next()).
Forward(hop[2].IP).
Forward(hop[2].AddrPort).
Message(address.FromPubKey(hop[2].HeaderKey), set.Next()).
Exit(port, prvs, pubs, payload).
Reply(hop[3].IP).
Reply(hop[3].AddrPort).
Message(address.FromPubKey(hop[3].HeaderKey), replies[0]).
Reply(hop[4].IP).
Reply(hop[4].AddrPort).
Message(address.FromPubKey(hop[4].HeaderKey), replies[1]).
Reply(client.IP).
Reply(client.AddrPort).
Message(address.FromPubKey(client.HeaderKey), replies[2]).
Assemble()
}

View File

@@ -2,6 +2,7 @@ package reply
import (
"net"
"net/netip"
"github.com/Indra-Labs/indra"
"github.com/Indra-Labs/indra/pkg/slice"
@@ -26,29 +27,42 @@ var (
// step the relay budges up it's message to the front of the packet and puts
// csprng random bytes into the remainder to the same length.
type OnionSkin struct {
// IP is the address of the next relay in the return leg of a circuit.
net.IP
// AddrPort is the address of the next relay in the return leg of a circuit.
netip.AddrPort
types.Onion
}
func (x *OnionSkin) Inner() types.Onion { return x.Onion }
func (x *OnionSkin) Insert(o types.Onion) { x.Onion = o }
func (x *OnionSkin) Len() int {
return magicbytes.Len + len(x.IP) + 1 + x.Onion.Len()
var ap []byte
var e error
if ap, e = x.AddrPort.MarshalBinary(); check(e) {
return -1
}
return magicbytes.Len + 1 + len(ap) + x.Onion.Len()
}
func (x *OnionSkin) Encode(b slice.Bytes, c *slice.Cursor) {
copy(b[*c:c.Inc(magicbytes.Len)], Magic)
b[*c] = byte(len(x.IP))
copy(b[c.Inc(1):c.Inc(len(x.IP))], x.IP)
var ap []byte
var e error
if ap, e = x.AddrPort.MarshalBinary(); check(e) {
return
}
b[*c] = byte(len(ap))
x.Onion.Encode(b, c)
}
func (x *OnionSkin) Decode(b slice.Bytes, c *slice.Cursor) (e error) {
if len(b[*c:]) < MinLen {
return magicbytes.TooShort(len(b[*c:]), MinLen, string(Magic))
if len(b[*c:]) < MinLen-magicbytes.Len {
return magicbytes.TooShort(len(b[*c:]), MinLen-magicbytes.Len, string(Magic))
}
apLen := b[*c]
apBytes := b[c.Inc(1):c.Inc(int(apLen))]
if e = x.AddrPort.UnmarshalBinary(apBytes); check(e) {
return
}
ipLen := b[*c]
x.IP = net.IP(b[c.Inc(1):c.Inc(int(ipLen))])
return
}

View File

@@ -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 = "4a1ab0f39c1c71fa5f9e0045ec701f671643ec6e"
ParentGitCommit = "6ee53acb90e5a9d67a327f8794745a0fac1b7e7e"
// BuildTime stores the time when the current binary was built.
BuildTime = "2022-12-24T12:28:37Z"
BuildTime = "2022-12-24T14:07:35Z"
// SemVer lists the (latest) git tag on the build.
SemVer = "v0.0.228"
SemVer = "v0.0.229"
// 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 = 228
Patch = 229
)
// Version returns a pretty printed version information string.