Files
indra/pkg/onions/forward/forward.go

90 lines
2.7 KiB
Go

package forward
import (
"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/onions/crypt"
"github.com/indra-labs/indra/pkg/onions/end"
"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"
"github.com/indra-labs/indra/pkg/util/splice"
"net/netip"
"reflect"
)
var (
log = log2.GetLogger()
fails = log.E.Chk
)
const (
ForwardMagic = "forw"
ForwardLen = magic.Len + 1 + splice.AddrLen
)
type Forward struct {
AddrPort *netip.AddrPort
ont.Onion
}
func (x *Forward) Account(res *sess.Data, sm *sess.Manager,
s *sessions.Data, last bool) (skip bool, sd *sessions.Data) {
res.Billable = append(res.Billable, s.Header.Bytes)
res.PostAcct = append(res.PostAcct,
func() {
sm.DecSession(s.Header.Bytes, int(s.Node.RelayRate)*len(res.B),
true, "forward")
})
return
}
func (x *Forward) Decode(s *splice.Splice) (e error) {
if e = magic.TooShort(s.Remaining(), ForwardLen-magic.Len,
ForwardMagic); fails(e) {
return
}
s.ReadAddrPort(&x.AddrPort)
return
}
func (x *Forward) Encode(s *splice.Splice) error {
log.T.F("encoding %s %s", reflect.TypeOf(x),
x.AddrPort.String(),
)
return x.Onion.Encode(s.Magic(ForwardMagic).AddrPort(x.AddrPort))
}
func (x *Forward) GetOnion() interface{} { return x }
func (x *Forward) Handle(s *splice.Splice, p ont.Onion, ng ont.Ngin) (e error) {
// Forward the whole buffer received onwards. Usually there will be a
// crypt.Layer under this which will be unwrapped by the receiver.
if x.AddrPort.String() == ng.Mgr().GetLocalNodeAddress().String() {
// it is for us, we want to unwrap the next part.
ng.HandleMessage(splice.BudgeUp(s), x)
} else {
switch on1 := p.(type) {
case *crypt.Crypt:
sess := ng.Mgr().FindSessionByHeader(on1.ToPriv)
if sess != nil {
ng.Mgr().DecSession(sess.Header.Bytes,
int(ng.Mgr().GetLocalNodeRelayRate())*s.Len(),
false, "forward")
}
}
// we need to forward this message onion.
ng.Mgr().Send(x.AddrPort, splice.BudgeUp(s))
}
return e
}
func (x *Forward) Len() int { return ForwardLen + x.Onion.Len() }
func (x *Forward) Magic() string { return ForwardMagic }
func (x *Forward) Wrap(inner ont.Onion) { x.Onion = inner }
func NewForward(addr *netip.AddrPort) ont.Onion { return &Forward{AddrPort: addr, Onion: &end.End{}} }
func forwardGen() coding.Codec { return &Forward{} }
func init() { reg.Register(ForwardMagic, forwardGen) }