mirror of
https://github.com/go-i2p/go-i2p.git
synced 2025-07-04 13:32:52 -04:00
103 lines
2.0 KiB
Go
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:])
|
|
}
|