Files
go-i2p/lib/tunnel/delivery.go
2016-01-29 07:22:31 -05:00

103 lines
2.0 KiB
Go

package tunnel
import (
"encoding/binary"
)
const (
DT_LOCAL = iota
DT_TUNNEL
DT_ROUTER
DT_UNUSED
)
type DelayFactor byte
type DeliveryInstructions []byte
func (di DeliveryInstructions) DeliveryType() byte {
return (di[0] & 0x30) >> 4
}
func (di DeliveryInstructions) IsFragmented() bool {
return (di[0] & 0x08) == 0x08
}
// get the tunnel id in this devilevery instrcutions or 0 if not applicable
func (di DeliveryInstructions) TunnelID() (tid uint32) {
if di.DeliveryType() == DT_TUNNEL {
// TODO(psi): what if this is 0?
tid = binary.BigEndian.Uint32(di[1:5])
}
return
}
// do we have a delay factor?
func (di DeliveryInstructions) HasDelay() bool {
return (di[0] & 0x10) == 0x10
}
// get the delay factor if it exists
func (di DeliveryInstructions) Delay() (d DelayFactor) {
if di.HasDelay() {
t := di.DeliveryType()
if t == DT_TUNNEL {
d = DelayFactor(di[37])
} else if t == DT_ROUTER {
d = DelayFactor(di[36])
}
}
return
}
func (di DeliveryInstructions) HasExtendedOptions() bool {
return (di[0] & 0x04) == 0x04
}
// get the to hash for these delivery instructions or nil if not applicable
func (di DeliveryInstructions) ToHash() (h []byte) {
t := di.DeliveryType()
if t == DT_TUNNEL {
h = di[5:37]
} else if t == DT_ROUTER || t == DT_LOCAL {
h = di[4:36]
}
return
}
// get the i2np message id or 0 if not applicable
func (di DeliveryInstructions) MessageID() (msgid uint32) {
if di.IsFragmented() {
idx := 1
t := di.DeliveryType()
if t == DT_TUNNEL {
idx += 36
} else if t == DT_ROUTER {
idx += 32
}
if di.HasDelay() {
idx++
}
msgid = binary.BigEndian.Uint32(di[idx:])
}
return
}
// get the size of the associated i2np fragment
func (di DeliveryInstructions) GetFragmentSize() uint16 {
idx := 5
t := di.DeliveryType()
if t == DT_TUNNEL {
idx += 36
} else if t == DT_ROUTER {
idx += 32
}
if di.HasDelay() {
idx++
}
if di.HasExtendedOptions() {
// add extended options length to idx
}
return binary.BigEndian.Uint16(di[idx:])
}