Files
indra/pkg/wire/reverse/reverse.go

65 lines
1.9 KiB
Go

package reverse
import (
"net"
"net/netip"
"github.com/indra-labs/indra"
log2 "github.com/indra-labs/indra/pkg/proc/log"
"github.com/indra-labs/indra/pkg/types"
"github.com/indra-labs/indra/pkg/util/slice"
"github.com/indra-labs/indra/pkg/wire/magicbytes"
)
const (
MagicString = "rv"
Len = magicbytes.Len + 1 + net.IPv6len + 2
)
var (
log = log2.GetLogger(indra.PathBase)
check = log.E.Chk
Magic = slice.Bytes(MagicString)
_ types.Onion = &OnionSkin{}
)
// OnionSkin is reply messages, distinct from forward.OnionSkin messages in that
// the header encryption uses a different secret than the payload. The magic
// bytes signal this to the relay that receives this, which then looks up the
// PayloadHey matching the To address in the message header. And lastly, each
// 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 {
// 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 Len + x.Onion.Len() }
func (x *OnionSkin) Encode(b slice.Bytes, c *slice.Cursor) {
copy(b[*c:c.Inc(magicbytes.Len)], Magic)
var ap []byte
var e error
if ap, e = x.AddrPort.MarshalBinary(); check(e) {
return
}
b[*c] = byte(len(ap))
copy(b[c.Inc(1):c.Inc(Len-magicbytes.Len-1)], ap)
x.Onion.Encode(b, c)
}
func (x *OnionSkin) Decode(b slice.Bytes, c *slice.Cursor) (e error) {
if len(b[*c:]) < Len-magicbytes.Len {
return magicbytes.TooShort(len(b[*c:]), Len-magicbytes.Len, string(Magic))
}
apLen := b[*c]
apBytes := b[c.Inc(1):c.Inc(Len-magicbytes.Len-1)]
x.AddrPort = &netip.AddrPort{}
if e = x.AddrPort.UnmarshalBinary(apBytes[:apLen]); check(e) {
return
}
return
}