110 lines
2.7 KiB
Go
110 lines
2.7 KiB
Go
package response
|
|
|
|
import (
|
|
"github.com/indra-labs/indra/pkg/crypto/nonce"
|
|
"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/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/slice"
|
|
"github.com/indra-labs/indra/pkg/util/splice"
|
|
"reflect"
|
|
)
|
|
|
|
var (
|
|
log = log2.GetLogger()
|
|
fails = log.E.Chk
|
|
)
|
|
|
|
const (
|
|
ResponseMagic = "resp"
|
|
ResponseLen = magic.Len +
|
|
slice.Uint32Len +
|
|
slice.Uint16Len +
|
|
nonce.IDLen + 1
|
|
)
|
|
|
|
type Response struct {
|
|
ID nonce.ID
|
|
Port uint16
|
|
Load byte
|
|
slice.Bytes
|
|
}
|
|
|
|
func NewResponse(id nonce.ID, port uint16, res slice.Bytes, load byte) ont.Onion {
|
|
return &Response{ID: id, Port: port, Bytes: res, Load: load}
|
|
}
|
|
|
|
func (x *Response) Account(res *sess.Data, sm *sess.Manager,
|
|
s *sessions.Data, last bool) (skip bool, sd *sessions.Data) {
|
|
return
|
|
}
|
|
|
|
func (x *Response) Decode(s *splice.Splice) (e error) {
|
|
if e = magic.TooShort(s.Remaining(), ResponseLen-magic.Len,
|
|
ResponseMagic); fails(e) {
|
|
return
|
|
}
|
|
s.
|
|
ReadID(&x.ID).
|
|
ReadUint16(&x.Port).
|
|
ReadByte(&x.Load).
|
|
ReadBytes(&x.Bytes)
|
|
return
|
|
}
|
|
|
|
func (x *Response) Encode(s *splice.Splice) (e error) {
|
|
log.T.Ln("encoding", reflect.TypeOf(x)) // x.Keys, x.Port, x.Load, x.Bytes.ToBytes(),
|
|
|
|
s.
|
|
Magic(ResponseMagic).
|
|
ID(x.ID).
|
|
Uint16(x.Port).
|
|
Byte(x.Load).
|
|
Bytes(x.Bytes)
|
|
return
|
|
}
|
|
|
|
func (x *Response) GetOnion() interface{} { return x }
|
|
|
|
func (x *Response) Handle(s *splice.Splice, p ont.Onion, ng ont.Ngin) (e error) {
|
|
pending := ng.Pending().Find(x.ID)
|
|
log.T.F("searching for pending Keys %s", x.ID)
|
|
if pending != nil {
|
|
for i := range pending.Billable {
|
|
se := ng.Mgr().FindSessionByPubkey(pending.Billable[i])
|
|
if se != nil {
|
|
typ := "response"
|
|
relayRate := se.Node.RelayRate
|
|
dataSize := s.Len()
|
|
switch i {
|
|
case 0, 1:
|
|
dataSize = pending.SentSize
|
|
case 2:
|
|
se.Node.Lock()
|
|
for j := range se.Node.Services {
|
|
if se.Node.Services[j].Port == x.Port {
|
|
relayRate = se.Node.Services[j].RelayRate / 2
|
|
typ = "exit"
|
|
break
|
|
}
|
|
}
|
|
se.Node.Unlock()
|
|
}
|
|
ng.Mgr().DecSession(se.Header.Bytes, int(relayRate)*dataSize, true, typ)
|
|
}
|
|
}
|
|
ng.Pending().ProcessAndDelete(x.ID, nil, x.Bytes)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (x *Response) Len() int { return ResponseLen + len(x.Bytes) }
|
|
func (x *Response) Magic() string { return ResponseMagic }
|
|
func (x *Response) Wrap(inner ont.Onion) {}
|
|
func init() { reg.Register(ResponseMagic, responseGen) }
|
|
func responseGen() coding.Codec { return &Response{} }
|