stutter elimination frenzy [===----]

This commit is contained in:
l0k18
2023-07-04 19:16:05 +01:00
parent 7999bf7e5a
commit a6de03eaae
21 changed files with 216 additions and 161 deletions

View File

@@ -8,11 +8,11 @@ import (
"github.com/indra-labs/indra/pkg/engine/node"
"github.com/indra-labs/indra/pkg/engine/payments"
"github.com/indra-labs/indra/pkg/engine/services"
"github.com/indra-labs/indra/pkg/onions/adaddresses"
"github.com/indra-labs/indra/pkg/onions/adload"
"github.com/indra-labs/indra/pkg/onions/adpeer"
"github.com/indra-labs/indra/pkg/onions/adproto"
"github.com/indra-labs/indra/pkg/onions/adservices"
"github.com/indra-labs/indra/pkg/onions/ad"
"github.com/indra-labs/indra/pkg/onions/ad/addresses"
"github.com/indra-labs/indra/pkg/onions/ad/load"
"github.com/indra-labs/indra/pkg/onions/ad/peer"
services2 "github.com/indra-labs/indra/pkg/onions/ad/services"
log2 "github.com/indra-labs/indra/pkg/proc/log"
"github.com/indra-labs/indra/pkg/util/multi"
"github.com/multiformats/go-multiaddr"
@@ -36,10 +36,10 @@ const DefaultAdExpiry = time.Hour * 24 * 7 // one week
// long time but services might change more often and load will be updated
// whenever it dramatically changes or every few minutes.
type NodeAds struct {
Peer *adpeer.Ad
Address *adaddresses.Ad
Services *adservices.Ad
Load *adload.Ad
Peer *peer.Ad
Address *addresses.Ad
Services *services2.Ad
Load *load.Ad
}
// GetMultiaddrs returns a node's listener addresses.
@@ -55,11 +55,11 @@ func GetMultiaddrs(n *node.Node) (ma []multiaddr.Multiaddr, e error) {
}
// GenerateAds takes a node.Node and creates the NodeAds matching it.
func GenerateAds(n *node.Node, load byte) (na *NodeAds, e error) {
func GenerateAds(n *node.Node, ld byte) (na *NodeAds, e error) {
expiry := time.Now().Add(DefaultAdExpiry)
var svcs []adservices.Service
var svcs []services2.Service
for i := range n.Services {
svcs = append(svcs, adservices.Service{
svcs = append(svcs, services2.Service{
Port: n.Services[i].Port,
RelayRate: n.Services[i].RelayRate,
})
@@ -77,37 +77,37 @@ func GenerateAds(n *node.Node, load byte) (na *NodeAds, e error) {
addrPorts[i] = &addy
}
na = &NodeAds{
Peer: &adpeer.Ad{
Ad: adproto.Ad{
Peer: &peer.Ad{
Ad: ad.Ad{
ID: nonce.NewID(),
Key: n.Identity.Pub,
Expiry: expiry,
},
RelayRate: n.RelayRate,
},
Address: &adaddresses.Ad{
Ad: adproto.Ad{
Address: &addresses.Ad{
Ad: ad.Ad{
ID: nonce.NewID(),
Key: n.Identity.Pub,
Expiry: expiry,
},
Addresses: addrPorts,
},
Services: &adservices.Ad{
Ad: adproto.Ad{
Services: &services2.Ad{
Ad: ad.Ad{
ID: nonce.NewID(),
Key: n.Identity.Pub,
Expiry: expiry,
},
Services: svcs,
},
Load: &adload.Ad{
Ad: adproto.Ad{
Load: &load.Ad{
Ad: ad.Ad{
ID: nonce.NewID(),
Key: n.Identity.Pub,
Expiry: time.Now().Add(time.Minute * 10),
},
Load: load,
Load: ld,
},
}
return

View File

@@ -1,7 +1,7 @@
package engine
import (
"github.com/indra-labs/indra/pkg/onions/adintro"
"github.com/indra-labs/indra/pkg/onions/ad/intro"
"github.com/indra-labs/indra/pkg/onions/exit"
"github.com/indra-labs/indra/pkg/onions/getbalance"
"github.com/indra-labs/indra/pkg/onions/message"
@@ -57,7 +57,9 @@ func (ng *Engine) SendGetBalance(alice, bob *sessions.Data, hook responses.Callb
// SendHiddenService dispatches a hiddenservice message, providing a relay the
// ability to refer clients to the hidden service and initiate connections.
func (ng *Engine) SendHiddenService(id nonce.ID, key *crypto.Prv, relayRate uint32, port uint16, expiry time.Time, alice, bob *sessions.Data, svc *services.Service, hook responses.Callback) (in *adintro.Ad, e error) {
func (ng *Engine) SendHiddenService(id nonce.ID, key *crypto.Prv, relayRate uint32,
port uint16, expiry time.Time, alice, bob *sessions.Data, svc *services.Service,
hook responses.Callback) (in *intro.Ad, e error) {
hops := sess.StandardCircuit()
s := make(sessions.Sessions, len(hops))
@@ -69,7 +71,7 @@ func (ng *Engine) SendHiddenService(id nonce.ID, key *crypto.Prv, relayRate uint
if addr, e = multi.AddrToAddrPort(alice.Node.PickAddress(ng.Mgr().Protocols)); fails(e) {
return
}
in = adintro.New(id, key, &addr, relayRate, port, expiry)
in = intro.New(id, key, &addr, relayRate, port, expiry)
o := MakeHiddenService(in, alice, bob, c, ng.KeySet, ng.Mgr().Protocols)
log.D.F("%s sending out hidden service onion %s",
ng.Mgr().GetLocalNodeAddressString(),
@@ -83,7 +85,7 @@ func (ng *Engine) SendHiddenService(id nonce.ID, key *crypto.Prv, relayRate uint
// SendIntroQuery delivers a query for a specified hidden service public key.
func (ng *Engine) SendIntroQuery(id nonce.ID, hsk *crypto.Pub,
alice, bob *sessions.Data, hook func(in *adintro.Ad)) {
alice, bob *sessions.Data, hook func(in *intro.Ad)) {
fn := func(id nonce.ID, ifc interface{}, b slice.Bytes) (e error) {
s := splice.Load(b, slice.NewCursor())
@@ -91,9 +93,9 @@ func (ng *Engine) SendIntroQuery(id nonce.ID, hsk *crypto.Pub,
if e = on.Decode(s); fails(e) {
return
}
var oni *adintro.Ad
var oni *intro.Ad
var ok bool
if oni, ok = on.(*adintro.Ad); !ok {
if oni, ok = on.(*intro.Ad); !ok {
return
}
hook(oni)

View File

@@ -8,7 +8,7 @@ import (
"github.com/indra-labs/indra/pkg/engine/sessions"
headers2 "github.com/indra-labs/indra/pkg/headers"
"github.com/indra-labs/indra/pkg/hidden"
"github.com/indra-labs/indra/pkg/onions/adintro"
"github.com/indra-labs/indra/pkg/onions/ad/intro"
"github.com/indra-labs/indra/pkg/onions/confirmation"
"github.com/indra-labs/indra/pkg/onions/crypt"
"github.com/indra-labs/indra/pkg/onions/end"
@@ -123,7 +123,7 @@ func (o Skins) GetBalance(id nonce.ID, ep *exit.ExitPoint) Skins {
// HiddenService is a message that delivers an intro and a referral RoutingHeader
// to enable a relay to introduce a client to a hidden service.
func (o Skins) HiddenService(in *adintro.Ad, point *exit.ExitPoint) Skins {
func (o Skins) HiddenService(in *intro.Ad, point *exit.ExitPoint) Skins {
return append(o, hiddenservice.NewHiddenService(in, point))
}
@@ -213,7 +213,7 @@ func MakeGetBalance(p getbalance.GetBalanceParams,
// MakeHiddenService constructs a hiddenservice message for designating
// introducers to refer clients to hidden services.
func MakeHiddenService(in *adintro.Ad, alice, bob *sessions.Data,
func MakeHiddenService(in *intro.Ad, alice, bob *sessions.Data,
c sessions.Circuit, ks *crypto.KeySet,
p protocols.NetworkProtocols) Skins {

View File

@@ -5,16 +5,16 @@ import (
"errors"
"fmt"
"github.com/indra-labs/indra/pkg/ad"
"github.com/indra-labs/indra/pkg/onions/adload"
"github.com/indra-labs/indra/pkg/onions/ad/load"
"github.com/indra-labs/indra/pkg/util/slice"
"github.com/libp2p/go-libp2p/core/host"
"github.com/libp2p/go-libp2p/core/peer"
"reflect"
"github.com/indra-labs/indra/pkg/onions/adaddresses"
"github.com/indra-labs/indra/pkg/onions/adintro"
"github.com/indra-labs/indra/pkg/onions/adpeer"
"github.com/indra-labs/indra/pkg/onions/adservices"
"github.com/indra-labs/indra/pkg/onions/ad/addresses"
"github.com/indra-labs/indra/pkg/onions/ad/intro"
peer2 "github.com/indra-labs/indra/pkg/onions/ad/peer"
"github.com/indra-labs/indra/pkg/onions/ad/services"
"github.com/indra-labs/indra/pkg/onions/reg"
"github.com/indra-labs/indra/pkg/util/splice"
pubsub "github.com/libp2p/go-libp2p-pubsub"
@@ -96,12 +96,12 @@ func (ng *Engine) HandleAd(p *pubsub.Message) (e error) {
}
var ok bool
switch c.(type) {
case *adaddresses.Ad:
case *addresses.Ad:
log.D.Ln("received", reflect.TypeOf(c), "from gossip network")
var addr *adaddresses.Ad
if addr, ok = c.(*adaddresses.Ad); !ok {
var addr *addresses.Ad
if addr, ok = c.(*addresses.Ad); !ok {
return fmt.Errorf(ErrWrongTypeDecode,
adaddresses.Magic, reflect.TypeOf(c).String())
addresses.Magic, reflect.TypeOf(c).String())
} else if !addr.Validate() {
return errors.New("addr ad failed validation")
}
@@ -112,15 +112,15 @@ func (ng *Engine) HandleAd(p *pubsub.Message) (e error) {
return
}
if e = ng.Listener.Host.
Peerstore().Put(id, adaddresses.Magic, s.GetAll().ToBytes()); fails(e) {
Peerstore().Put(id, addresses.Magic, s.GetAll().ToBytes()); fails(e) {
return
}
case *adintro.Ad:
case *intro.Ad:
log.D.Ln("received", reflect.TypeOf(c), "from gossip network")
var intr *adintro.Ad
if intr, ok = c.(*adintro.Ad); !ok {
var intr *intro.Ad
if intr, ok = c.(*intro.Ad); !ok {
return fmt.Errorf(ErrWrongTypeDecode,
adintro.Magic, reflect.TypeOf(c).String())
intro.Magic, reflect.TypeOf(c).String())
} else if !intr.Validate() {
return errors.New("intro ad failed validation")
}
@@ -131,15 +131,15 @@ func (ng *Engine) HandleAd(p *pubsub.Message) (e error) {
return
}
if e = ng.Listener.Host.
Peerstore().Put(id, adintro.Magic, s.GetAll().ToBytes()); fails(e) {
Peerstore().Put(id, intro.Magic, s.GetAll().ToBytes()); fails(e) {
return
}
case *adload.Ad:
case *load.Ad:
log.D.Ln("received", reflect.TypeOf(c), "from gossip network")
var lod *adload.Ad
if lod, ok = c.(*adload.Ad); !ok {
var lod *load.Ad
if lod, ok = c.(*load.Ad); !ok {
return fmt.Errorf(ErrWrongTypeDecode,
adaddresses.Magic, reflect.TypeOf(c).String())
addresses.Magic, reflect.TypeOf(c).String())
} else if !lod.Validate() {
return errors.New("load ad failed validation")
}
@@ -150,15 +150,15 @@ func (ng *Engine) HandleAd(p *pubsub.Message) (e error) {
return
}
if e = ng.Listener.Host.
Peerstore().Put(id, adservices.Magic, s.GetAll().ToBytes()); fails(e) {
Peerstore().Put(id, services.Magic, s.GetAll().ToBytes()); fails(e) {
return
}
case *adpeer.Ad:
case *peer2.Ad:
log.D.Ln("received", reflect.TypeOf(c), "from gossip network")
var pa *adpeer.Ad
if pa, ok = c.(*adpeer.Ad); !ok {
var pa *peer2.Ad
if pa, ok = c.(*peer2.Ad); !ok {
return fmt.Errorf(ErrWrongTypeDecode,
adpeer.Magic, reflect.TypeOf(c).String())
peer2.Magic, reflect.TypeOf(c).String())
} else if !pa.Validate() {
return errors.New("peer ad failed validation")
}
@@ -169,15 +169,15 @@ func (ng *Engine) HandleAd(p *pubsub.Message) (e error) {
return
}
if e = ng.Listener.Host.
Peerstore().Put(id, adpeer.Magic, s.GetAll().ToBytes()); fails(e) {
Peerstore().Put(id, peer2.Magic, s.GetAll().ToBytes()); fails(e) {
return
}
case *adservices.Ad:
case *services.Ad:
log.D.Ln("received", reflect.TypeOf(c), "from gossip network")
var sa *adservices.Ad
if sa, ok = c.(*adservices.Ad); !ok {
var sa *services.Ad
if sa, ok = c.(*services.Ad); !ok {
return fmt.Errorf(ErrWrongTypeDecode,
adservices.Magic, reflect.TypeOf(c).String())
services.Magic, reflect.TypeOf(c).String())
} else if !sa.Validate() {
return errors.New("services ad failed validation")
}
@@ -188,7 +188,7 @@ func (ng *Engine) HandleAd(p *pubsub.Message) (e error) {
return
}
if e = ng.Listener.Host.
Peerstore().Put(id, adservices.Magic, s.GetAll().ToBytes()); fails(e) {
Peerstore().Put(id, services.Magic, s.GetAll().ToBytes()); fails(e) {
return
}
}

View File

@@ -3,11 +3,11 @@ package engine
import (
"github.com/indra-labs/indra"
"github.com/indra-labs/indra/pkg/crypto/nonce"
"github.com/indra-labs/indra/pkg/onions/adaddresses"
"github.com/indra-labs/indra/pkg/onions/adintro"
"github.com/indra-labs/indra/pkg/onions/adload"
"github.com/indra-labs/indra/pkg/onions/adpeer"
"github.com/indra-labs/indra/pkg/onions/adservices"
"github.com/indra-labs/indra/pkg/onions/ad/addresses"
"github.com/indra-labs/indra/pkg/onions/ad/intro"
"github.com/indra-labs/indra/pkg/onions/ad/load"
"github.com/indra-labs/indra/pkg/onions/ad/peer"
"github.com/indra-labs/indra/pkg/onions/ad/services"
"github.com/indra-labs/indra/pkg/util/multi"
"github.com/indra-labs/indra/pkg/util/splice"
"net/netip"
@@ -51,7 +51,7 @@ func TestEngine_PeerStore(t *testing.T) {
addy, _ := multi.AddrToAddrPort(adz[i])
addrs[i] = &addy
}
newAddressAd := adaddresses.New(nonce.NewID(),
newAddressAd := addresses.New(nonce.NewID(),
engines[0].Mgr().GetLocalNodeIdentityPrv(),
addrs,
time.Now().Add(time.Hour*24*7))
@@ -63,7 +63,7 @@ func TestEngine_PeerStore(t *testing.T) {
t.FailNow()
}
time.Sleep(time.Second)
newIntroAd := adintro.New(nonce.NewID(),
newIntroAd := intro.New(nonce.NewID(),
engines[0].Mgr().GetLocalNodeIdentityPrv(),
engines[0].Mgr().GetLocalNodeAddress(),
20000, 443,
@@ -76,7 +76,7 @@ func TestEngine_PeerStore(t *testing.T) {
t.FailNow()
}
time.Sleep(time.Second)
newLoadAd := adload.New(nonce.NewID(),
newLoadAd := load.New(nonce.NewID(),
engines[0].Mgr().GetLocalNodeIdentityPrv(),
17,
time.Now().Add(time.Hour*24*7))
@@ -88,7 +88,7 @@ func TestEngine_PeerStore(t *testing.T) {
t.FailNow()
}
time.Sleep(time.Second)
newPeerAd := adpeer.New(nonce.NewID(),
newPeerAd := peer.New(nonce.NewID(),
engines[0].Mgr().GetLocalNodeIdentityPrv(),
20000,
time.Now().Add(time.Hour*24*7))
@@ -101,9 +101,9 @@ func TestEngine_PeerStore(t *testing.T) {
t.FailNow()
}
time.Sleep(time.Second * 1)
newServiceAd := adservices.New(nonce.NewID(),
newServiceAd := services.New(nonce.NewID(),
engines[0].Mgr().GetLocalNodeIdentityPrv(),
[]adservices.Service{{20000, 54321}},
[]services.Service{{20000, 54321}},
time.Now().Add(time.Hour*24*7))
ss := splice.New(newServiceAd.Len())
if e = newServiceAd.Encode(ss); fails(e) {

View File

@@ -6,7 +6,7 @@ import (
"github.com/indra-labs/indra/pkg/crypto/ciph"
"github.com/indra-labs/indra/pkg/crypto/nonce"
"github.com/indra-labs/indra/pkg/engine/services"
"github.com/indra-labs/indra/pkg/onions/adintro"
"github.com/indra-labs/indra/pkg/onions/ad/intro"
"github.com/indra-labs/indra/pkg/onions/consts"
log2 "github.com/indra-labs/indra/pkg/proc/log"
"github.com/indra-labs/indra/pkg/util/slice"
@@ -42,7 +42,7 @@ type Hidden struct {
//
// todo: looks like that addr parameter should be in a logging closure derived from the key.
func (hr *Hidden) AddHiddenService(svc *services.Service, key *crypto.Prv,
in *adintro.Ad, addr string) {
in *intro.Ad, addr string) {
pk := crypto.DerivePub(key).ToBytes()
hr.Lock()
log.D.F("%s added hidden service with key %s", addr, pk)
@@ -71,10 +71,9 @@ func (hr *Hidden) AddIntro(pk *crypto.Pub, intro *Introduction) {
// AddIntroToHiddenService adds an intro to a given hidden service.
//
// todo: this looks like it isn't used.
func (hr *Hidden) AddIntroToHiddenService(key crypto.PubBytes, in *adintro.Ad) {
func (hr *Hidden) AddIntroToHiddenService(key crypto.PubBytes, in *intro.Ad) {
hr.Lock()
hr.Services[key].CurrentIntros = append(hr.Services[key].
CurrentIntros, in)
hr.Services[key].CurrentIntros = append(hr.Services[key].CurrentIntros, in)
hr.Unlock()
}
@@ -192,7 +191,7 @@ func (hr *Hidden) FindHiddenService(key crypto.PubBytes) (
return
}
// FindIntroduction returns the adintro.Ad matching a provided public key bytes.
// FindIntroduction returns the intro.Ad matching a provided public key bytes.
func (hr *Hidden) FindIntroduction(key crypto.PubBytes) (intro *Introduction) {
hr.Lock()
intro = hr.FindIntroductionUnsafe(key)
@@ -213,7 +212,7 @@ func (hr *Hidden) FindIntroductionUnsafe(
// FindKnownIntro searches non-local intros for a matching public key bytes.
//
// todo: this definitely should be part of peerstore.
func (hr *Hidden) FindKnownIntro(key crypto.PubBytes) (intro *adintro.Ad) {
func (hr *Hidden) FindKnownIntro(key crypto.PubBytes) (intro *intro.Ad) {
hr.Lock()
intro = hr.FindKnownIntroUnsafe(key)
hr.Unlock()
@@ -221,25 +220,25 @@ func (hr *Hidden) FindKnownIntro(key crypto.PubBytes) (intro *adintro.Ad) {
}
// FindKnownIntroUnsafe searches for a KnownIntro without locking.
func (hr *Hidden) FindKnownIntroUnsafe(key crypto.PubBytes) (intro *adintro.Ad) {
func (hr *Hidden) FindKnownIntroUnsafe(key crypto.PubBytes) (intro *intro.Ad) {
var ok bool
if intro, ok = hr.KnownIntros[key]; ok {
}
return
}
// Introduction is the combination of an adintro.Ad and a ReplyHeader, used to
// Introduction is the combination of an intro.Ad and a ReplyHeader, used to
// forward the Route message from a client and establish the connection between
// client and hidden service.
type Introduction struct {
Intro *adintro.Ad
Intro *intro.Ad
ReplyHeader
}
// KnownIntros is a key/value store of hidden service intros we know of.
//
// todo: This definitely should be peerstore
type KnownIntros map[crypto.PubBytes]*adintro.Ad
type KnownIntros map[crypto.PubBytes]*intro.Ad
// LocalHiddenService is a hidden service being served from this node.
type LocalHiddenService struct {
@@ -247,10 +246,10 @@ type LocalHiddenService struct {
// Prv is the private key for the hidden service.
Prv *crypto.Prv
// CurrentIntros are adintro.Ad that are current for this hidden service.
//
// todo: why more than one?
CurrentIntros []*adintro.Ad
// CurrentIntros are intro.Ad that are current for this hidden service. Not sure
// yet how many this should be. 6 or more, it really depends, perhaps have it
// scale up if demand exceeds supply to some sort of reasonable ceiling.
CurrentIntros []*intro.Ad
// Service is the definition of the hidden service. There should be a server
// listening on or forwarding from the service port on localhost that provides

View File

@@ -1,5 +1,7 @@
// Package adproto is an abstract message type that composes the common elements of all ads - nonce ID, public key (identity), expiry and signature.
package adproto
// Package ad is an abstract message type that composes the common elements of all ads - nonce ID, public key (identity), expiry and signature.
//
// The concrete ad types are in subfolders of this package.
package ad
import (
"github.com/indra-labs/indra/pkg/crypto"

View File

@@ -1,4 +1,4 @@
package adproto
package ad
import (
"github.com/indra-labs/indra"

View File

@@ -1,5 +1,5 @@
// Package adaddresses defines the message format that provides the network multi-address of a peer with a given public identity key.
package adaddresses
// Package addresses defines the message format that provides the network multi-address of a peer with a given public identity key.
package addresses
import (
"fmt"
@@ -8,8 +8,8 @@ import (
"github.com/indra-labs/indra/pkg/crypto/sha256"
"github.com/indra-labs/indra/pkg/engine/coding"
"github.com/indra-labs/indra/pkg/engine/magic"
"github.com/indra-labs/indra/pkg/onions/adintro"
"github.com/indra-labs/indra/pkg/onions/adproto"
"github.com/indra-labs/indra/pkg/onions/ad"
"github.com/indra-labs/indra/pkg/onions/ad/intro"
"github.com/indra-labs/indra/pkg/onions/reg"
log2 "github.com/indra-labs/indra/pkg/proc/log"
"github.com/indra-labs/indra/pkg/util/slice"
@@ -34,26 +34,26 @@ const (
// "/service/N" where N is the index of the entry. A zero value at an index
// signals to stop scanning for more subsequent values.
type Ad struct {
adproto.Ad
ad.Ad
Addresses []*netip.AddrPort
}
var _ coding.Codec = &Ad{}
// New ...
// New creates a new addresses.Ad.
func New(id nonce.ID, key *crypto.Prv, addrs []*netip.AddrPort,
expiry time.Time) (sv *Ad) {
k := crypto.DerivePub(key)
sv = &Ad{
Ad: adproto.Ad{
Ad: ad.Ad{
ID: id,
Key: k,
Expiry: expiry,
},
Addresses: addrs,
}
s := splice.New(adintro.Len)
s := splice.New(intro.Len)
sv.SpliceNoSig(s)
hash := sha256.Single(s.GetUntil(s.GetCursor()))
var e error
@@ -63,6 +63,7 @@ func New(id nonce.ID, key *crypto.Prv, addrs []*netip.AddrPort,
return
}
// Decode a splice.Splice's next bytes into an Ad.
func (x *Ad) Decode(s *splice.Splice) (e error) {
var i, count uint32
s.ReadID(&x.ID).
@@ -80,17 +81,23 @@ func (x *Ad) Decode(s *splice.Splice) (e error) {
return
}
// Encode an Ad into a splice.Splice's next bytes.
func (x *Ad) Encode(s *splice.Splice) (e error) {
x.Splice(s)
return
}
// GetOnion returns nothing because there isn't an onion inside an Ad.
func (x *Ad) GetOnion() interface{} { return nil }
func (x *Ad) Len() int { return adproto.Len + len(x.Addresses)*AddrLen + slice.Uint32Len + 2 }
// Len returns the length of bytes required to encode the Ad, based on the number
// of Addresses inside it.
func (x *Ad) Len() int { return ad.Len + len(x.Addresses)*AddrLen + slice.Uint32Len + 2 }
func (x *Ad) Magic() string { return "" }
// Magic bytes that identify this message
func (x *Ad) Magic() string { return Magic }
// Sign the encoded form of the bytes in order to authorise it.
func (x *Ad) Sign(prv *crypto.Prv) (e error) {
s := splice.New(x.Len())
if e = x.Encode(s); fails(e) {
@@ -108,17 +115,20 @@ func (x *Ad) Sign(prv *crypto.Prv) (e error) {
return nil
}
// Splice together an Ad.
func (x *Ad) Splice(s *splice.Splice) {
x.SpliceNoSig(s)
s.Signature(x.Sig)
}
// SpliceNoSig splices until the signature.
func (x *Ad) SpliceNoSig(s *splice.Splice) {
ServiceSplice(s, x.ID, x.Key, x.Addresses, x.Expiry)
Splice(s, x.ID, x.Key, x.Addresses, x.Expiry)
}
// Validate checks that the signature matches the public key.
func (x *Ad) Validate() (valid bool) {
s := splice.New(adintro.Len - magic.Len)
s := splice.New(intro.Len - magic.Len)
x.SpliceNoSig(s)
hash := sha256.Single(s.GetUntil(s.GetCursor()))
key, e := x.Sig.Recover(hash)
@@ -131,7 +141,9 @@ func (x *Ad) Validate() (valid bool) {
return false
}
func ServiceSplice(s *splice.Splice, id nonce.ID, key *crypto.Pub, addrs []*netip.AddrPort, expiry time.Time) {
// Splice is a function that serializes the parts of an Ad.
func Splice(s *splice.Splice, id nonce.ID, key *crypto.Pub,
addrs []*netip.AddrPort, expiry time.Time) {
s.Magic(Magic).
ID(id).
@@ -143,6 +155,6 @@ func ServiceSplice(s *splice.Splice, id nonce.ID, key *crypto.Pub, addrs []*neti
s.Time(expiry)
}
func init() { reg.Register(Magic, serviceAdGen) }
func init() { reg.Register(Magic, Gen) }
func serviceAdGen() coding.Codec { return &Ad{} }
func Gen() coding.Codec { return &Ad{} }

View File

@@ -1,4 +1,4 @@
package adaddresses
package addresses
import (
"github.com/indra-labs/indra"

View File

@@ -1,8 +1,8 @@
// Package adintro defines a message type that provides information about an introduction point for a hidden service.
package adintro
// Package intro defines a message type that provides information about an introduction point for a hidden service.
package intro
import (
"github.com/indra-labs/indra/pkg/onions/adproto"
"github.com/indra-labs/indra/pkg/onions/ad"
"github.com/indra-labs/indra/pkg/onions/reg"
log2 "github.com/indra-labs/indra/pkg/proc/log"
"net/netip"
@@ -25,11 +25,15 @@ var (
const (
Magic = "inad"
Len = adproto.Len + splice.AddrLen + 1 + slice.Uint16Len + slice.Uint32Len
Len = ad.Len + splice.AddrLen + 1 + slice.Uint16Len + slice.Uint32Len
)
// Ad is an Intro message that signals that a hidden service can be accessed from
// a given relay at a given address.
//
// todo: needs to be plural too!
type Ad struct {
adproto.Ad
ad.Ad
AddrPort *netip.AddrPort // Introducer address.
Port uint16 // Well known port of protocol available.
RelayRate uint32 // mSat/Mb
@@ -37,6 +41,7 @@ type Ad struct {
var _ coding.Codec = &Ad{}
// Decode an Ad out of the next bytes of a splice.Splice.
func (x *Ad) Decode(s *splice.Splice) (e error) {
if e = magic.TooShort(s.Remaining(), Len-magic.Len,
Magic); fails(e) {
@@ -54,27 +59,36 @@ func (x *Ad) Decode(s *splice.Splice) (e error) {
return
}
// Encode an Ad into the next bytes of a splice.Splice.
func (x *Ad) Encode(s *splice.Splice) (e error) {
log.T.S("encoding", reflect.TypeOf(x), x)
x.Splice(s)
return
}
func (x *Ad) GetOnion() interface{} { return x }
// GetOnion returns nil because there is no onion inside.
func (x *Ad) GetOnion() interface{} { return nil }
// Len returns the length of the binary encoded Ad.
//
// todo: plural.
func (x *Ad) Len() int { return Len }
// Magic is the identifier indicating an Ad is encoded in the following bytes.
func (x *Ad) Magic() string { return Magic }
// Splice serializes an Ad into a splice.Splice.
func (x *Ad) Splice(s *splice.Splice) {
x.SpliceNoSig(s)
s.Signature(x.Sig)
}
// SpliceNoSig serializes the Ad but stops at the signature.
func (x *Ad) SpliceNoSig(s *splice.Splice) {
IntroSplice(s, x.ID, x.Key, x.AddrPort, x.RelayRate, x.Port, x.Expiry)
}
// Validate checks the signature matches the public key of the Ad.
func (x *Ad) Validate() bool {
s := splice.New(Len - magic.Len)
x.SpliceNoSig(s)
@@ -89,6 +103,7 @@ func (x *Ad) Validate() bool {
return false
}
// IntroSplice creates the message part up to the signature for an Ad.
func IntroSplice(
s *splice.Splice,
id nonce.ID,
@@ -108,6 +123,7 @@ func IntroSplice(
Time(expires)
}
// New creates a new Ad and signs it.
func New(
id nonce.ID,
key *crypto.Prv,
@@ -120,7 +136,7 @@ func New(
pk := crypto.DerivePub(key)
in = &Ad{
Ad: adproto.Ad{
Ad: ad.Ad{
ID: id,
Key: pk,
Expiry: expires,
@@ -139,6 +155,6 @@ func New(
return
}
func init() { reg.Register(Magic, introGen) }
func init() { reg.Register(Magic, Gen) }
func introGen() coding.Codec { return &Ad{} }
func Gen() coding.Codec { return &Ad{} }

View File

@@ -1,4 +1,4 @@
package adintro
package intro
import (
"github.com/indra-labs/indra"

View File

@@ -1,5 +1,5 @@
// Package adload provides a message type that provides information about the current load level of a node identified by its public key.
package adload
// Package load provides a message type that provides information about the current load level of a node identified by its public key.
package load
import (
"github.com/indra-labs/indra/pkg/crypto"
@@ -7,7 +7,7 @@ import (
"github.com/indra-labs/indra/pkg/crypto/sha256"
"github.com/indra-labs/indra/pkg/engine/coding"
"github.com/indra-labs/indra/pkg/engine/magic"
"github.com/indra-labs/indra/pkg/onions/adproto"
"github.com/indra-labs/indra/pkg/onions/ad"
"github.com/indra-labs/indra/pkg/onions/reg"
log2 "github.com/indra-labs/indra/pkg/proc/log"
"github.com/indra-labs/indra/pkg/util/splice"
@@ -22,12 +22,12 @@ var (
const (
Magic = "load"
Len = adproto.Len + 1
Len = ad.Len + 1
)
// Ad stores a specification for the fee rate and existence of a peer.
type Ad struct {
adproto.Ad
ad.Ad
Load byte
}
@@ -39,7 +39,7 @@ func New(id nonce.ID, key *crypto.Prv, load byte,
k := crypto.DerivePub(key)
sv = &Ad{
Ad: adproto.Ad{
Ad: ad.Ad{
ID: id,
Key: k,
Expiry: expiry,

View File

@@ -1,4 +1,4 @@
package adload
package load
import (
"testing"

View File

@@ -1,5 +1,5 @@
// Package adpeer provides a message type that provides the base information, identity key and relay rate for an Indra relay.
package adpeer
// Package peer provides a message type that provides the base information, identity key and relay rate for an Indra relay.
package peer
import (
"github.com/indra-labs/indra/pkg/crypto"
@@ -7,8 +7,8 @@ import (
"github.com/indra-labs/indra/pkg/crypto/sha256"
"github.com/indra-labs/indra/pkg/engine/coding"
"github.com/indra-labs/indra/pkg/engine/magic"
"github.com/indra-labs/indra/pkg/onions/adintro"
"github.com/indra-labs/indra/pkg/onions/adproto"
"github.com/indra-labs/indra/pkg/onions/ad"
"github.com/indra-labs/indra/pkg/onions/ad/intro"
"github.com/indra-labs/indra/pkg/onions/reg"
log2 "github.com/indra-labs/indra/pkg/proc/log"
"github.com/indra-labs/indra/pkg/util/slice"
@@ -24,13 +24,13 @@ var (
const (
Magic = "pead"
Len = adproto.Len +
Len = ad.Len +
slice.Uint32Len
)
// Ad stores a specification for the fee rate and existence of a peer.
type Ad struct {
adproto.Ad
ad.Ad
RelayRate uint32
}
@@ -40,7 +40,7 @@ var _ coding.Codec = &Ad{}
func New(id nonce.ID, key *crypto.Prv, relayRate uint32,
expiry time.Time) (sv *Ad) {
s := splice.New(adintro.Len)
s := splice.New(intro.Len)
k := crypto.DerivePub(key)
Splice(s, id, k, relayRate, expiry)
hash := sha256.Single(s.GetUntil(s.GetCursor()))
@@ -50,10 +50,10 @@ func New(id nonce.ID, key *crypto.Prv, relayRate uint32,
return nil
}
sv = &Ad{
Ad: adproto.Ad{
Ad: ad.Ad{
ID: id,
Key: k,
Expiry: time.Now().Add(adproto.TTL),
Expiry: time.Now().Add(ad.TTL),
Sig: sign,
},
RelayRate: relayRate,
@@ -106,7 +106,7 @@ func (x *Ad) SpliceNoSig(s *splice.Splice) {
}
func (x *Ad) Validate() (valid bool) {
s := splice.New(adintro.Len - magic.Len)
s := splice.New(intro.Len - magic.Len)
x.SpliceNoSig(s)
hash := sha256.Single(s.GetUntil(s.GetCursor()))
key, e := x.Sig.Recover(hash)

View File

@@ -1,4 +1,4 @@
package adpeer
package peer
import (
"testing"

View File

@@ -1,5 +1,5 @@
// Package adservices provides a message type for advertising what kinds of exit services a peer provides to clients, including the port number and the cost per megabyte of data.
package adservices
// Package services provides a message type for advertising what kinds of exit services a peer provides to clients, including the port number and the cost per megabyte of data.
package services
import (
"fmt"
@@ -8,8 +8,8 @@ import (
"github.com/indra-labs/indra/pkg/crypto/sha256"
"github.com/indra-labs/indra/pkg/engine/coding"
"github.com/indra-labs/indra/pkg/engine/magic"
"github.com/indra-labs/indra/pkg/onions/adintro"
"github.com/indra-labs/indra/pkg/onions/adproto"
"github.com/indra-labs/indra/pkg/onions/ad"
"github.com/indra-labs/indra/pkg/onions/ad/intro"
"github.com/indra-labs/indra/pkg/onions/reg"
log2 "github.com/indra-labs/indra/pkg/proc/log"
"github.com/indra-labs/indra/pkg/util/slice"
@@ -38,7 +38,7 @@ type Service struct {
// "/service/N" where N is the index of the entry. A zero value at an index
// signals to stop scanning for more subsequent values.
type Ad struct {
adproto.Ad
ad.Ad
Services []Service
}
@@ -50,14 +50,14 @@ func New(id nonce.ID, key *crypto.Prv, services []Service,
k := crypto.DerivePub(key)
sv = &Ad{
Ad: adproto.Ad{
Ad: ad.Ad{
ID: id,
Key: k,
Expiry: expiry,
},
Services: services,
}
s := splice.New(adintro.Len)
s := splice.New(intro.Len)
sv.SpliceNoSig(s)
hash := sha256.Single(s.GetUntil(s.GetCursor()))
var e error
@@ -90,7 +90,7 @@ func (x *Ad) Encode(s *splice.Splice) (e error) {
func (x *Ad) GetOnion() interface{} { return nil }
func (x *Ad) Len() int { return adproto.Len + len(x.Services)*ServiceLen + slice.Uint32Len }
func (x *Ad) Len() int { return ad.Len + len(x.Services)*ServiceLen + slice.Uint32Len }
func (x *Ad) Magic() string { return "" }
@@ -121,7 +121,7 @@ func (x *Ad) SpliceNoSig(s *splice.Splice) {
}
func (x *Ad) Validate() (valid bool) {
s := splice.New(adintro.Len - magic.Len)
s := splice.New(intro.Len - magic.Len)
x.SpliceNoSig(s)
hash := sha256.Single(s.GetUntil(s.GetCursor()))
key, e := x.Sig.Recover(hash)

View File

@@ -1,4 +1,4 @@
package adservices
package services
import (
"github.com/indra-labs/indra"
@@ -19,7 +19,7 @@ func TestServiceAd(t *testing.T) {
var e error
pr, _, _ := crypto.NewSigner()
id := nonce.NewID()
sv := New(id, pr, []Service{{80, 50000},{443, 50000}}, time.Now().Add(time.Hour))
sv := New(id, pr, []Service{{80, 50000}, {443, 50000}}, time.Now().Add(time.Hour))
log.D.S("service", sv)
s := splice.New(sv.Len())
if e = sv.Encode(s); fails(e) {

View File

@@ -7,7 +7,7 @@ package hiddenservice
import (
"github.com/indra-labs/indra/pkg/hidden"
intro "github.com/indra-labs/indra/pkg/onions/adintro"
"github.com/indra-labs/indra/pkg/onions/ad/intro"
"github.com/indra-labs/indra/pkg/onions/consts"
"github.com/indra-labs/indra/pkg/onions/end"
"github.com/indra-labs/indra/pkg/onions/exit"
@@ -32,28 +32,38 @@ var (
)
const (
HiddenServiceMagic = "hids"
HiddenServiceLen = magic.Len +
Magic = "hids"
Len = magic.Len +
intro.Len +
3*sha256.Len +
nonce.IVLen*3 +
consts.RoutingHeaderLen
)
// HiddenService is a message providing an Intro and the necessary Ciphers,
// Nonces and RoutingHeaderBytes to forward a Route message through to the hidden
// service, using the client's reply RoutingHeader.
type HiddenService struct {
// Intro of the hidden service.
Intro intro.Ad
// Ciphers is a set of 3 symmetric ciphers that are to be used in their
// given order over the reply message from the service.
crypto.Ciphers
// Nonces are the nonces to use with the cipher when creating the encryption
// for the reply message, they are common with the crypts in the header.
crypto.Nonces
hidden.RoutingHeaderBytes
ont.Onion
}
func (x *HiddenService) Account(res *sess.Data, sm *sess.Manager, s *sessions.Data, last bool) (skip bool,
sd *sessions.Data) {
// Account the traffic for the relay handling this message.
func (x *HiddenService) Account(res *sess.Data, sm *sess.Manager, s *sessions.Data,
last bool) (skip bool, sd *sessions.Data) {
res.ID = x.Intro.ID
res.Billable = append(res.Billable, s.Header.Bytes)
@@ -61,9 +71,9 @@ func (x *HiddenService) Account(res *sess.Data, sm *sess.Manager, s *sessions.Da
return
}
// Decode the HiddenService message from the next bytes of a Splice.
func (x *HiddenService) Decode(s *splice.Splice) (e error) {
if e = magic.TooShort(s.Remaining(), HiddenServiceLen-magic.Len,
HiddenServiceMagic); fails(e) {
if e = magic.TooShort(s.Remaining(), Len-magic.Len, Magic); fails(e) {
return
}
if e = x.Intro.Decode(s); fails(e) {
@@ -77,16 +87,19 @@ func (x *HiddenService) Decode(s *splice.Splice) (e error) {
return
}
// Encode a HiddenService into a the next bytes of a Splice.
func (x *HiddenService) Encode(s *splice.Splice) (e error) {
log.T.S("encoding", reflect.TypeOf(x),
x.Intro.ID, x.Intro.Key, x.Intro.AddrPort, x.Ciphers, x.Nonces, x.RoutingHeaderBytes,
)
x.Intro.Splice(s.Magic(HiddenServiceMagic))
x.Intro.Splice(s.Magic(Magic))
return x.Onion.Encode(s.Ciphers(x.Ciphers).Nonces(x.Nonces))
}
// GetOnion returns the inner onion or remaining parts of the message prototype.
func (x *HiddenService) GetOnion() interface{} { return x }
// Handle defines how the ont.Ngin should deal with this onion type.
func (x *HiddenService) Handle(s *splice.Splice, p ont.Onion, ng ont.Ngin) (e error) {
log.D.S("intro", x.Intro)
log.D.F("%s adding introduction for key %s",
@@ -106,10 +119,18 @@ func (x *HiddenService) Handle(s *splice.Splice, p ont.Onion, ng ont.Ngin) (e er
return
}
func (x *HiddenService) Len() int { return HiddenServiceLen + x.Onion.Len() }
func (x *HiddenService) Magic() string { return HiddenServiceMagic }
// Len returns the length of the onion starting from this one (used to size a
// Splice).
func (x *HiddenService) Len() int { return Len + x.Onion.Len() }
// Magic bytes identifying a HiddenService message is up next.
func (x *HiddenService) Magic() string { return Magic }
// Wrap places another onion inside this one in its slot.
func (x *HiddenService) Wrap(inner ont.Onion) { x.Onion = inner }
// NewHiddenService generates a new HiddenService data structure and returns it
// as an ont.Onion interface.
func NewHiddenService(in *intro.Ad, point *exit.ExitPoint) ont.Onion {
return &HiddenService{
Intro: *in,
@@ -118,5 +139,8 @@ func NewHiddenService(in *intro.Ad, point *exit.ExitPoint) ont.Onion {
Onion: end.NewEnd(),
}
}
func hiddenServiceGen() coding.Codec { return &HiddenService{} }
func init() { reg.Register(HiddenServiceMagic, hiddenServiceGen) }
// Gen is a factory function for a HiddenService.
func Gen() coding.Codec { return &HiddenService{} }
func init() { reg.Register(Magic, Gen) }

View File

@@ -12,9 +12,9 @@ import (
"github.com/indra-labs/indra/pkg/engine/sessions"
"github.com/indra-labs/indra/pkg/engine/transport"
headers2 "github.com/indra-labs/indra/pkg/headers"
intro "github.com/indra-labs/indra/pkg/onions/adintro"
"github.com/indra-labs/indra/pkg/onions/exit"
"github.com/indra-labs/indra/pkg/onions/getbalance"
intro "github.com/indra-labs/indra/pkg/onions/intro"
"github.com/indra-labs/indra/pkg/onions/ont"
"github.com/indra-labs/indra/pkg/onions/reg"
log2 "github.com/indra-labs/indra/pkg/proc/log"

View File

@@ -1,4 +1,4 @@
// Package introquery is an onion message that verifies a relay is an introducer for a given hidden service, returning its adintro.Ad.
// Package introquery is an onion message that verifies a relay is an introducer for a given hidden service, returning its intro.Ad.
//
// After receiving this message if the intro is valid a client can use a route message to start a connection.
package introquery
@@ -12,7 +12,7 @@ import (
"github.com/indra-labs/indra/pkg/engine/sess"
"github.com/indra-labs/indra/pkg/engine/sessions"
"github.com/indra-labs/indra/pkg/hidden"
"github.com/indra-labs/indra/pkg/onions/adintro"
"github.com/indra-labs/indra/pkg/onions/ad/intro"
"github.com/indra-labs/indra/pkg/onions/crypt"
"github.com/indra-labs/indra/pkg/onions/end"
"github.com/indra-labs/indra/pkg/onions/exit"
@@ -89,11 +89,11 @@ func (x *IntroQuery) Handle(s *splice.Splice, p ont.Onion, ng ont.Ngin) (e error
log.D.Ln(ng.Mgr().GetLocalNodeAddressString(), "handling introquery", x.ID,
x.Key.ToBased32Abbreviated())
var ok bool
var il *adintro.Ad
var il *intro.Ad
if il, ok = ng.GetHidden().KnownIntros[x.Key.ToBytes()]; !ok {
// if the reply is zeroes the querant knows it needs to retry at a
// different relay
il = &adintro.Ad{}
il = &intro.Ad{}
ng.GetHidden().Unlock()
log.E.Ln("intro not known")
return