diff --git a/pkg/engine/eng_senders.go b/pkg/engine/eng_senders.go index 5ca533a5..95755eda 100644 --- a/pkg/engine/eng_senders.go +++ b/pkg/engine/eng_senders.go @@ -50,7 +50,7 @@ func (ng *Engine) SendGetBalance(alice, bob *sessions.Data, hook responses.Callb 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 *onions.Intro) { + hook responses.Callback) (in *onions.IntroAd) { hops := sess.StandardCircuit() s := make(sessions.Sessions, len(hops)) @@ -58,7 +58,7 @@ func (ng *Engine) SendHiddenService(id nonce.ID, key *crypto.Prv, se := ng.Manager.SelectHops(hops, s, "sendhiddenservice") var c sessions.Circuit copy(c[:], se[:len(c)]) - in = onions.NewIntro(id, key, alice.Node.AddrPort, relayRate, port, expiry) + in = onions.NewIntroAd(id, key, alice.Node.AddrPort, relayRate, port, expiry) o := onions.MakeHiddenService(in, alice, bob, c, ng.KeySet) log.D.F("%s sending out hidden service onion %s", ng.Manager.GetLocalNodeAddressString(), @@ -71,7 +71,7 @@ func (ng *Engine) SendHiddenService(id nonce.ID, key *crypto.Prv, } func (ng *Engine) SendIntroQuery(id nonce.ID, hsk *crypto.Pub, - alice, bob *sessions.Data, hook func(in *onions.Intro)) { + alice, bob *sessions.Data, hook func(in *onions.IntroAd)) { fn := func(id nonce.ID, ifc interface{}, b slice.Bytes) (e error) { s := splice.Load(b, slice.NewCursor()) @@ -79,9 +79,9 @@ func (ng *Engine) SendIntroQuery(id nonce.ID, hsk *crypto.Pub, if e = on.Decode(s); fails(e) { return } - var oni *onions.Intro + var oni *onions.IntroAd var ok bool - if oni, ok = on.(*onions.Intro); !ok { + if oni, ok = on.(*onions.IntroAd); !ok { return } hook(oni) diff --git a/pkg/engine/onions/adintro.go b/pkg/engine/onions/adintro.go index 2255faaa..4673853a 100644 --- a/pkg/engine/onions/adintro.go +++ b/pkg/engine/onions/adintro.go @@ -18,10 +18,10 @@ import ( ) const ( - IntroMagic = "intr" + IntroMagic = "inad" IntroLen = magic.Len + nonce.IDLen + - crypto.PubKeyLen + 1 + 1 + + crypto.PubKeyLen + 1 + 4 + splice.AddrLen + slice.Uint16Len + slice.Uint32Len + @@ -29,7 +29,7 @@ const ( crypto.SigLen ) -type Intro struct { +type IntroAd struct { ID nonce.ID // Ensures never a repeated signature. Key *crypto.Pub // Hidden service address. AddrPort *netip.AddrPort // Introducer address. @@ -39,7 +39,7 @@ type Intro struct { Sig crypto.SigBytes } -func (x *Intro) Account( +func (x *IntroAd) Account( res *sess.Data, sm *sess.Manager, s *sessions.Data, @@ -50,13 +50,14 @@ func (x *Intro) Account( return } -func (x *Intro) Decode(s *splice.Splice) (e error) { +func (x *IntroAd) Decode(s *splice.Splice) (e error) { if e = magic.TooShort(s.Remaining(), IntroLen-magic.Len, IntroMagic); fails(e) { return } - s.ReadID(&x.ID). + s. + ReadID(&x.ID). ReadPubkey(&x.Key). ReadAddrPort(&x.AddrPort). ReadUint32(&x.RelayRate). @@ -66,24 +67,24 @@ func (x *Intro) Decode(s *splice.Splice) (e error) { return } -func (x *Intro) Encode(s *splice.Splice) (e error) { +func (x *IntroAd) Encode(s *splice.Splice) (e error) { log.T.S("encoding", reflect.TypeOf(x), x.ID, x.AddrPort.String(), x.Expiry, x.Sig, ) - x.Splice(s.Magic(IntroMagic)) + x.Splice(s) return } -func (x *Intro) GetOnion() interface{} { return x } +func (x *IntroAd) GetOnion() interface{} { return x } // Gossip means adding to the node's peer message list which will be gossiped by // the libp2p network of Indra peers. -func (x *Intro) Gossip(sm *sess.Manager, c qu.C) { +func (x *IntroAd) Gossip(sm *sess.Manager, c qu.C) { log.D.F("propagating hidden service intro for %s", x.Key.ToBased32Abbreviated()) } -func (x *Intro) Handle(s *splice.Splice, p Onion, ng Ngin) (e error) { +func (x *IntroAd) Handle(s *splice.Splice, p Onion, ng Ngin) (e error) { log.D.Ln("handling intro") ng.GetHidden().Lock() valid := x.Validate() @@ -117,37 +118,19 @@ func (x *Intro) Handle(s *splice.Splice, p Onion, ng Ngin) (e error) { return } -func (x *Intro) Len() int { return IntroLen } -func (x *Intro) Magic() string { return IntroMagic } +func (x *IntroAd) Len() int { return IntroLen } +func (x *IntroAd) Magic() string { return IntroMagic } -func (x *Intro) Splice(s *splice.Splice) { +func (x *IntroAd) Splice(s *splice.Splice) { x.SpliceNoSig(s) s.Signature(x.Sig) } -func IntroSplice( - s *splice.Splice, - id nonce.ID, - key *crypto.Pub, - ap *netip.AddrPort, - relayRate uint32, - port uint16, - expires time.Time, -) { - - s.ID(id). - Pubkey(key). - AddrPort(ap). - Uint32(relayRate). - Uint16(port). - Time(expires) -} - -func (x *Intro) SpliceNoSig(s *splice.Splice) { +func (x *IntroAd) SpliceNoSig(s *splice.Splice) { IntroSplice(s, x.ID, x.Key, x.AddrPort, x.RelayRate, x.Port, x.Expiry) } -func (x *Intro) Validate() bool { +func (x *IntroAd) Validate() bool { s := splice.New(IntroLen - magic.Len) x.SpliceNoSig(s) hash := sha256.Single(s.GetUntil(s.GetCursor())) @@ -161,19 +144,38 @@ func (x *Intro) Validate() bool { return false } -func (x *Intro) Wrap(inner Onion) {} +func (x *IntroAd) Wrap(inner Onion) {} -func NewIntro( +func IntroSplice( + s *splice.Splice, + id nonce.ID, + key *crypto.Pub, + ap *netip.AddrPort, + relayRate uint32, + port uint16, + expires time.Time, +) { + + s.Magic(IntroMagic). + ID(id). + Pubkey(key). + AddrPort(ap). + Uint32(relayRate). + Uint16(port). + Time(expires) +} + +func NewIntroAd( id nonce.ID, key *crypto.Prv, ap *netip.AddrPort, relayRate uint32, port uint16, expires time.Time, -) (in *Intro) { +) (in *IntroAd) { pk := crypto.DerivePub(key) - s := splice.New(IntroLen - magic.Len) + s := splice.New(IntroLen) IntroSplice(s, id, pk, ap, relayRate, port, expires) hash := sha256.Single(s.GetUntil(s.GetCursor())) var e error @@ -181,7 +183,7 @@ func NewIntro( if sign, e = crypto.Sign(key, hash); fails(e) { return nil } - in = &Intro{ + in = &IntroAd{ ID: id, Key: pk, AddrPort: ap, @@ -194,4 +196,4 @@ func NewIntro( } func init() { Register(IntroMagic, introGen) } -func introGen() coding.Codec { return &Intro{} } +func introGen() coding.Codec { return &IntroAd{} } diff --git a/pkg/engine/onions/adintro_test.go b/pkg/engine/onions/adintro_test.go index c2a3e08c..b27bab90 100644 --- a/pkg/engine/onions/adintro_test.go +++ b/pkg/engine/onions/adintro_test.go @@ -1,6 +1,7 @@ package onions import ( + "github.com/indra-labs/indra/pkg/util/splice" "testing" "time" @@ -12,26 +13,17 @@ import ( ) func TestOnionSkins_IntroAd(t *testing.T) { - log2.SetLogLevel(log2.Debug) + log2.SetLogLevel(log2.Trace) var e error - pr, ks, _ := crypto.NewSigner() + pr, _, _ := crypto.NewSigner() id := nonce.NewID() - in := NewIntro(id, pr, slice.GenerateRandomAddrPortIPv6(), - 0, 0, time.Now().Add(time.Hour)) - var prvs crypto.Privs - for i := range prvs { - prvs[i] = ks.Next() + in := NewIntroAd(id, pr, slice.GenerateRandomAddrPortIPv6(), + 20000, 80, time.Now().Add(time.Hour)) + log.D.S("intro", in) + s := splice.New(in.Len()) + if e = in.Encode(s); fails(e) { + t.FailNow() } - var pubs crypto.Pubs - for i := range pubs { - pubs[i] = crypto.DerivePub(prvs[i]) - } - on1 := Skins{}. - Intro(id, pr, in.AddrPort, time.Now().Add(time.Hour)) - on1 = append(on1, &End{}) - on := on1.Assemble() - s := Encode(on) - log.D.S(s.GetAll().ToBytes()) s.SetCursor(0) var onc coding.Codec if onc = Recognise(s); onc == nil { @@ -43,16 +35,32 @@ func TestOnionSkins_IntroAd(t *testing.T) { t.FailNow() } log.D.S(onc) - var intro *Intro + var intro *IntroAd var ok bool - if intro, ok = onc.(*Intro); !ok { + if intro, ok = onc.(*IntroAd); !ok { t.Error("did not unwrap expected type") t.FailNow() } + if intro.ID != in.ID { + t.Errorf("ID did not decode correctly") + t.FailNow() + } + if intro.Port != in.Port { + t.Errorf("port did not decode correctly") + t.FailNow() + } + if intro.RelayRate != in.RelayRate { + t.Errorf("relay rate did not decode correctly") + t.FailNow() + } if intro.AddrPort.String() != in.AddrPort.String() { t.Errorf("addrport did not decode correctly") t.FailNow() } + if !intro.Key.Equals(crypto.DerivePub(pr)) { + t.Errorf("public key did not decode correctly") + t.FailNow() + } if !intro.Validate() { t.Errorf("received intro did not validate") t.FailNow() diff --git a/pkg/engine/onions/adpeer.go b/pkg/engine/onions/adpeer.go index c9ba9c2b..b5d6ee67 100644 --- a/pkg/engine/onions/adpeer.go +++ b/pkg/engine/onions/adpeer.go @@ -5,6 +5,7 @@ import ( "github.com/indra-labs/indra/pkg/crypto" "github.com/indra-labs/indra/pkg/crypto/nonce" "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/engine/sess" "github.com/indra-labs/indra/pkg/engine/sessions" @@ -17,10 +18,13 @@ const ( PeerAdMagic = "prad" PeerAdLen = magic.Len + nonce.IDLen + - slice.Uint64Len + + crypto.PubKeyLen + + slice.Uint32Len + crypto.SigLen ) +var _ Ad = &PeerAd{} + // PeerAd is the root identity document for an Indra peer. It is indexed by the // Identity field, its public key. The slices found below it are derived via // concatenation of strings with the keys and hashing to generate a derived @@ -31,14 +35,28 @@ const ( // service from their introduction solicitation, and the index from the current // set is given by the hidden service. type PeerAd struct { - nonce.ID // To ensure no repeating message - Identity crypto.PubBytes - RelayRate int + nonce.ID // To ensure no repeating message + Identity *crypto.Pub // Must match signature. + RelayRate uint32 // Zero means not relaying. Sig crypto.SigBytes - // Addresses - first is address, nil for hidden services, - // hidden services have more than one, 6 or more are kept active. - Addresses []*AddressAd - ServiceInfos []ServiceAd +} + +func NewPeerAd( + id nonce.ID, + key *crypto.Prv, + relayRate uint32, +) (pa *PeerAd) { + + pa = &PeerAd{ + ID: id, + Identity: crypto.DerivePub(key), + RelayRate: relayRate, + } + var e error + if e = pa.Sign(key); fails(e) { + return + } + return } func (x *PeerAd) Account(res *sess.Data, sm *sess.Manager, s *sessions.Data, last bool) (skip bool, sd *sessions.Data) { @@ -47,19 +65,20 @@ func (x *PeerAd) Account(res *sess.Data, sm *sess.Manager, s *sessions.Data, las } func (x *PeerAd) Decode(s *splice.Splice) (e error) { - var v uint64 - s.ReadID(&x.ID).ReadUint64(&v) - s.ReadSignature(&x.Sig) - x.RelayRate = int(v) + s.ReadID(&x.ID). + ReadPubkey(&x.Identity). + ReadUint32(&x.RelayRate). + ReadSignature(&x.Sig) return nil } func (x *PeerAd) Encode(s *splice.Splice) (e error) { - s.ID(x.ID).Uint64(uint64(x.RelayRate)) + s.Magic(PeerAdMagic) + x.Splice(s) return nil } -func (x *PeerAd) GetOnion() interface{} { return nil } +func (x *PeerAd) GetOnion() interface{} { return nil } func (x *PeerAd) Gossip(sm *sess.Manager, c qu.C) {} func (x *PeerAd) Handle(s *splice.Splice, p Onion, ni Ngin) (e error) { return nil @@ -85,17 +104,30 @@ func (x *PeerAd) Sign(prv *crypto.Prv) (e error) { } func (x *PeerAd) Splice(s *splice.Splice) { - s. - ID(x.ID). - Uint64(uint64(x.RelayRate)) + s.ID(x.ID). + Pubkey(x.Identity). + Uint32(x.RelayRate). + Signature(x.Sig) } -func (x *PeerAd) Validate(s *splice.Splice) (pk *crypto.Pub) { - h := sha256.Single(s.GetRange(0, nonce.IDLen+slice.Uint64Len)) +func (x *PeerAd) SpliceNoSig(s *splice.Splice) { + s.ID(x.ID). + Pubkey(x.Identity). + Uint32(x.RelayRate). + Signature(x.Sig) +} + +func (x *PeerAd) Validate() (valid bool) { + s := splice.New(x.Len()) + x.SpliceNoSig(s) + h := sha256.Single(s.GetUntil(s.GetCursor())) var e error + var pk *crypto.Pub if pk, e = x.Sig.Recover(h); fails(e) { } - return + return pk != nil } func (x *PeerAd) Wrap(inner Onion) {} +func init() { Register(PeerAdMagic, peerAdGen) } +func peerAdGen() coding.Codec { return &PeerAd{} } diff --git a/pkg/engine/onions/adpeer_test.go b/pkg/engine/onions/adpeer_test.go index 7664ded8..d9bf37d2 100644 --- a/pkg/engine/onions/adpeer_test.go +++ b/pkg/engine/onions/adpeer_test.go @@ -1,50 +1,47 @@ package onions -// -//func TestOnionSkins_PeerAd(t *testing.T) { -// log2.SetLogLevel(log2.Debug) -// var e error -// pr, ks, _ := crypto.NewSigner() -// id := nonce.NewID() -// in := NewPeerAd(id, pr, slice.GenerateRandomAddrPortIPv6(), -// 0, 0, time.Now().Add(time.Hour)) -// var prvs crypto.Privs -// for i := range prvs { -// prvs[i] = ks.Next() -// } -// var pubs crypto.Pubs -// for i := range pubs { -// pubs[i] = crypto.DerivePub(prvs[i]) -// } -// on1 := Skins{}. -// PeerAd(id, pr, in.AddrPort, time.Now().Add(time.Hour)) -// on1 = append(on1, &End{}) -// on := on1.Assemble() -// s := Encode(on) -// log.D.S(s.GetAll().ToBytes()) -// s.SetCursor(0) -// var onc coding.Codec -// if onc = Recognise(s); onc == nil { -// t.Error("did not unwrap") -// t.FailNow() -// } -// if e = onc.Decode(s); fails(e) { -// t.Error("did not decode") -// t.FailNow() -// } -// log.D.S(onc) -// var intro *PeerAd -// var ok bool -// if intro, ok = onc.(*PeerAd); !ok { -// t.Error("did not unwrap expected type") -// t.FailNow() -// } -// if intro.AddrPort.String() != in.AddrPort.String() { -// t.Errorf("addrport did not decode correctly") -// t.FailNow() -// } -// if !intro.Validate() { -// t.Errorf("received intro did not validate") -// t.FailNow() -// } -//} +import ( + "github.com/indra-labs/indra/pkg/crypto" + "github.com/indra-labs/indra/pkg/crypto/nonce" + "github.com/indra-labs/indra/pkg/engine/coding" + log2 "github.com/indra-labs/indra/pkg/proc/log" + "github.com/indra-labs/indra/pkg/util/splice" + "testing" +) + +func TestOnionSkins_PeerAd(t *testing.T) { + log2.SetLogLevel(log2.Trace) + var e error + pr, _, _ := crypto.NewSigner() + id := nonce.NewID() + peerAd := NewPeerAd(id, pr, 20000) + s := splice.New(peerAd.Len()) + if e = peerAd.Encode(s); fails(e) { + t.FailNow() + } + s.SetCursor(0) + var onc coding.Codec + if onc = Recognise(s); onc == nil { + t.Error("did not unwrap") + t.FailNow() + } + if e = onc.Decode(s); fails(e) { + t.Error("did not decode") + t.FailNow() + } + log.D.S(onc) + var pa *PeerAd + var ok bool + if pa, ok = onc.(*PeerAd); !ok { + t.Error("did not unwrap expected type") + t.FailNow() + } + if pa.RelayRate != peerAd.RelayRate { + t.Errorf("relay rate did not decode correctly") + t.FailNow() + } + if !pa.Validate() { + t.Errorf("received intro did not validate") + t.FailNow() + } +} diff --git a/pkg/engine/onions/adservice.go b/pkg/engine/onions/adservice.go index 4e27f477..62f4c50c 100644 --- a/pkg/engine/onions/adservice.go +++ b/pkg/engine/onions/adservice.go @@ -6,6 +6,7 @@ import ( "github.com/indra-labs/indra/pkg/crypto/nonce" "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/engine/sess" "github.com/indra-labs/indra/pkg/engine/sessions" "github.com/indra-labs/indra/pkg/util/qu" @@ -14,9 +15,11 @@ import ( ) const ( - ServiceAdMagic = "intr" - ServiceAdLen = nonce.IDLen + - 2*slice.Uint16Len + + ServiceAdMagic = "svad" + ServiceAdLen = magic.Len + + nonce.IDLen + + crypto.PubKeyLen + + slice.Uint16Len + slice.Uint32Len + crypto.SigLen ) @@ -27,26 +30,29 @@ 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 ServiceAd struct { - ID nonce.ID // To ensure no repeating message - Index uint16 // This is the index in the slice from Peer. + ID nonce.ID // To ensure no repeating message. + Key *crypto.Pub // Server offering service. Port uint16 RelayRate uint32 Sig crypto.SigBytes } -func (x *ServiceAd) Account(res *sess.Data, sm *sess.Manager, s *sessions.Data, last bool) (skip bool, sd *sessions.Data) { +func (x *ServiceAd) Account(res *sess.Data, sm *sess.Manager, + s *sessions.Data, last bool) (skip bool, sd *sessions.Data) { + return false, nil } func (x *ServiceAd) Decode(s *splice.Splice) (e error) { s.ReadID(&x.ID). - ReadUint16(&x.Index). + ReadPubkey(&x.Key). ReadUint16(&x.Port). - ReadUint32(&x.RelayRate) + ReadUint32(&x.RelayRate). + ReadSignature(&x.Sig) return } func (x *ServiceAd) Encode(s *splice.Splice) (e error) { - x.Splice(s.Magic(ServiceAdMagic)) + x.Splice(s) return } @@ -81,22 +87,70 @@ func (x *ServiceAd) Sign(prv *crypto.Prv) (e error) { } func (x *ServiceAd) Splice(s *splice.Splice) { - s.ID(x.ID). - Uint16(x.Index). - Uint16(x.Port). - Uint32(x.RelayRate) + x.SpliceNoSig(s) + s.Signature(x.Sig) } -func (x *ServiceAd) Validate(s *splice.Splice) (pub *crypto.Pub) { - h := sha256.Single(s.GetRange(0, nonce.IDLen+2*slice.Uint16Len+ - slice.Uint64Len)) - var e error - if pub, e = x.Sig.Recover(h); fails(e) { +func (x *ServiceAd) SpliceNoSig(s *splice.Splice) { + ServiceSplice(s, x.ID, x.Key, x.RelayRate, x.Port) +} + +func (x *ServiceAd) Validate() (valid bool) { + s := splice.New(IntroLen - magic.Len) + x.SpliceNoSig(s) + hash := sha256.Single(s.GetUntil(s.GetCursor())) + key, e := x.Sig.Recover(hash) + if fails(e) { + return false } - return + if key.Equals(x.Key) { + return true + } + return false } func (x *ServiceAd) Wrap(inner Onion) {} +func ServiceSplice( + s *splice.Splice, + id nonce.ID, + key *crypto.Pub, + relayRate uint32, + port uint16, +) { + + s.Magic(ServiceAdMagic). + ID(id). + Pubkey(key). + Uint16(port). + Uint32(relayRate) +} + +func NewServiceAd( + id nonce.ID, + key *crypto.Prv, + relayRate uint32, + port uint16, +) (sv *ServiceAd) { + + s := splice.New(IntroLen) + k := crypto.DerivePub(key) + ServiceSplice(s, id, k, relayRate, port) + hash := sha256.Single(s.GetUntil(s.GetCursor())) + var e error + var sign crypto.SigBytes + if sign, e = crypto.Sign(key, hash); fails(e) { + return nil + } + sv = &ServiceAd{ + ID: id, + Key: k, + RelayRate: relayRate, + Port: port, + Sig: sign, + } + return +} + func init() { Register(ServiceAdMagic, serviceAdGen) } -func serviceAdGen() coding.Codec { return &Intro{} } +func serviceAdGen() coding.Codec { return &ServiceAd{} } diff --git a/pkg/engine/onions/adservice_test.go b/pkg/engine/onions/adservice_test.go new file mode 100644 index 00000000..a77b14ba --- /dev/null +++ b/pkg/engine/onions/adservice_test.go @@ -0,0 +1,56 @@ +package onions + +import ( + "github.com/indra-labs/indra/pkg/crypto" + "github.com/indra-labs/indra/pkg/crypto/nonce" + "github.com/indra-labs/indra/pkg/engine/coding" + log2 "github.com/indra-labs/indra/pkg/proc/log" + "github.com/indra-labs/indra/pkg/util/splice" + "testing" +) + +func TestOnionSkins_ServiceAd(t *testing.T) { + log2.SetLogLevel(log2.Trace) + var e error + pr, _, _ := crypto.NewSigner() + id := nonce.NewID() + sv := NewServiceAd(id, pr, 20000, 80) + log.D.S("service", sv) + s := splice.New(sv.Len()) + if e = sv.Encode(s); fails(e) { + t.FailNow() + } + s.SetCursor(0) + var onc coding.Codec + if onc = Recognise(s); onc == nil { + t.Error("did not unwrap") + t.FailNow() + } + if e = onc.Decode(s); fails(e) { + t.Error("did not decode") + t.FailNow() + } + log.D.S(onc) + var svcAd *ServiceAd + var ok bool + if svcAd, ok = onc.(*ServiceAd); !ok { + t.Error("did not unwrap expected type") + t.FailNow() + } + if svcAd.RelayRate != sv.RelayRate { + t.Errorf("relay rate did not decode correctly") + t.FailNow() + } + if svcAd.Port != sv.Port { + t.Errorf("port did not decode correctly") + t.FailNow() + } + if !svcAd.Key.Equals(crypto.DerivePub(pr)) { + t.Errorf("public key did not decode correctly") + t.FailNow() + } + if !svcAd.Validate() { + t.Errorf("received service ad did not validate") + t.FailNow() + } +} diff --git a/pkg/engine/onions/hidden.go b/pkg/engine/onions/hidden.go index d17d9cab..d66d1672 100644 --- a/pkg/engine/onions/hidden.go +++ b/pkg/engine/onions/hidden.go @@ -17,7 +17,7 @@ type Hidden struct { } func (hr *Hidden) AddHiddenService(svc *services.Service, key *crypto.Prv, - in *Intro, addr string) { + in *IntroAd, addr string) { pk := crypto.DerivePub(key).ToBytes() hr.Lock() log.I.F("%s added hidden service with key %s", addr, pk) @@ -42,7 +42,7 @@ func (hr *Hidden) AddIntro(pk *crypto.Pub, intro *Introduction) { hr.Unlock() } -func (hr *Hidden) AddIntroToHiddenService(key crypto.PubBytes, in *Intro) { +func (hr *Hidden) AddIntroToHiddenService(key crypto.PubBytes, in *IntroAd) { hr.Lock() hr.Services[key].CurrentIntros = append(hr.Services[key]. CurrentIntros, in) @@ -140,7 +140,7 @@ func (hr *Hidden) FindIntroductionUnsafe( return } -func (hr *Hidden) FindKnownIntro(key crypto.PubBytes) (intro *Intro) { +func (hr *Hidden) FindKnownIntro(key crypto.PubBytes) (intro *IntroAd) { hr.Lock() var ok bool if intro, ok = hr.KnownIntros[key]; ok { @@ -149,17 +149,17 @@ func (hr *Hidden) FindKnownIntro(key crypto.PubBytes) (intro *Intro) { return } -func (hr *Hidden) FindKnownIntroUnsafe(key crypto.PubBytes) (intro *Intro) { +func (hr *Hidden) FindKnownIntroUnsafe(key crypto.PubBytes) (intro *IntroAd) { var ok bool if intro, ok = hr.KnownIntros[key]; ok { } return } -type KnownIntros map[crypto.PubBytes]*Intro +type KnownIntros map[crypto.PubBytes]*IntroAd type LocalHiddenService struct { Prv *crypto.Prv - CurrentIntros []*Intro + CurrentIntros []*IntroAd *services.Service } type MyIntros map[crypto.PubBytes]*Introduction diff --git a/pkg/engine/onions/hiddenservice.go b/pkg/engine/onions/hiddenservice.go index 460f72ca..987d597b 100644 --- a/pkg/engine/onions/hiddenservice.go +++ b/pkg/engine/onions/hiddenservice.go @@ -20,7 +20,7 @@ const ( ) type HiddenService struct { - Intro Intro + Intro IntroAd // 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 diff --git a/pkg/engine/onions/introquery.go b/pkg/engine/onions/introquery.go index 0a3732f7..d220c379 100644 --- a/pkg/engine/onions/introquery.go +++ b/pkg/engine/onions/introquery.go @@ -73,11 +73,11 @@ func (x *IntroQuery) Handle(s *splice.Splice, p Onion, ng Ngin) (e error) { log.D.Ln(ng.Mgr().GetLocalNodeAddressString(), "handling introquery", x.ID, x.Key.ToBased32Abbreviated()) var ok bool - var il *Intro + var il *IntroAd 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 = &Intro{} + il = &IntroAd{} ng.GetHidden().Unlock() log.E.Ln("intro not known") return diff --git a/pkg/engine/onions/intros.go b/pkg/engine/onions/intros.go index 384f9dc8..65a7b65e 100644 --- a/pkg/engine/onions/intros.go +++ b/pkg/engine/onions/intros.go @@ -1,6 +1,6 @@ package onions type Introduction struct { - Intro *Intro + Intro *IntroAd ReplyHeader } diff --git a/pkg/engine/onions/onion_skins.go b/pkg/engine/onions/onion_skins.go index 81ae222f..82487fd7 100644 --- a/pkg/engine/onions/onion_skins.go +++ b/pkg/engine/onions/onion_skins.go @@ -213,7 +213,7 @@ func (h *Headers) ExitPoint() *ExitPoint { } } -func (o Skins) HiddenService(in *Intro, point *ExitPoint) Skins { +func (o Skins) HiddenService(in *IntroAd, point *ExitPoint) Skins { return append(o, &HiddenService{ Intro: *in, Ciphers: crypto.GenCiphers(point.Keys, point.ReturnPubs), @@ -224,7 +224,13 @@ func (o Skins) HiddenService(in *Intro, point *ExitPoint) Skins { func (o Skins) Intro(id nonce.ID, key *crypto.Prv, ap *netip.AddrPort, expires time.Time) (sk Skins) { - return append(o, NewIntro(id, key, ap, 0, 0, expires)) + return append(o, NewIntroAd(id, key, ap, 0, 0, expires)) +} + +func (o Skins) PeerAd(id nonce.ID, key *crypto.Prv, ap *netip.AddrPort, + relayRate uint32, port uint16, expires time.Time) (sk Skins) { + + return append(o, NewPeerAd(id, key, relayRate)) } func (o Skins) IntroQuery(id nonce.ID, hsk *crypto.Pub, exit *ExitPoint) Skins { @@ -267,7 +273,7 @@ func MakeGetBalance(p GetBalanceParams) Skins { RoutingHeader(headers.Return) } -func MakeHiddenService(in *Intro, alice, bob *sessions.Data, +func MakeHiddenService(in *IntroAd, alice, bob *sessions.Data, c sessions.Circuit, ks *crypto.KeySet) Skins { headers := GetHeaders(alice, bob, c, ks)