mirror of
https://github.com/go-i2p/go-i2p.git
synced 2025-07-06 06:24:20 -04:00
more delivery instruction details, hash fixes
This commit is contained in:
@ -29,10 +29,6 @@ end_date :: Date
|
|||||||
length -> 8 bytes
|
length -> 8 bytes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/hkparker/go-i2p/lib/tunnel"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Sizes or various components of a Lease
|
// Sizes or various components of a Lease
|
||||||
const (
|
const (
|
||||||
LEASE_SIZE = 44
|
LEASE_SIZE = 44
|
||||||
@ -53,8 +49,8 @@ func (lease Lease) TunnelGateway() (hash Hash) {
|
|||||||
//
|
//
|
||||||
// Parse the TunnelID Integer in the Lease.
|
// Parse the TunnelID Integer in the Lease.
|
||||||
//
|
//
|
||||||
func (lease Lease) TunnelID() tunnel.TunnelID {
|
func (lease Lease) TunnelID() uint32 {
|
||||||
return tunnel.TunnelID(
|
return uint32(
|
||||||
Integer(lease[LEASE_HASH_SIZE : LEASE_HASH_SIZE+LEASE_TUNNEL_ID_SIZE]),
|
Integer(lease[LEASE_HASH_SIZE : LEASE_HASH_SIZE+LEASE_TUNNEL_ID_SIZE]),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,9 @@ package tunnel
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
|
log "github.com/Sirupsen/logrus"
|
||||||
|
"github.com/hkparker/go-i2p/lib/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -51,8 +54,7 @@ Tunnel ID :: TunnelId
|
|||||||
|
|
||||||
To Hash ::
|
To Hash ::
|
||||||
32 bytes
|
32 bytes
|
||||||
Optional, present if delivery type is DESTINATION, ROUTER, or TUNNEL
|
Optional, present if delivery type is ROUTER, or TUNNEL
|
||||||
If DESTINATION, the SHA256 Hash of the destination
|
|
||||||
If ROUTER, the SHA256 Hash of the router
|
If ROUTER, the SHA256 Hash of the router
|
||||||
If TUNNEL, the SHA256 Hash of the gateway router
|
If TUNNEL, the SHA256 Hash of the gateway router
|
||||||
|
|
||||||
@ -140,19 +142,19 @@ type DeliveryInstructions []byte
|
|||||||
// Return if the DeliveryInstructions are of type FIRST_FRAGMENT or FOLLOW_ON_FRAGMENT.
|
// Return if the DeliveryInstructions are of type FIRST_FRAGMENT or FOLLOW_ON_FRAGMENT.
|
||||||
func (delivery_instructions DeliveryInstructions) Type() int {
|
func (delivery_instructions DeliveryInstructions) Type() int {
|
||||||
/*
|
/*
|
||||||
Check if the 7 bit of the Delivery Instructions
|
Check if the 7 bit of the Delivery Instructions
|
||||||
is set using binary AND operator to determine
|
is set using binary AND operator to determine
|
||||||
the Delivery Instructions type
|
the Delivery Instructions type
|
||||||
|
|
||||||
1xxxxxxx 0xxxxxxx
|
1xxxxxxx 0xxxxxxx
|
||||||
&10000000 &10000000
|
&10000000 &10000000
|
||||||
--------- ---------
|
--------- ---------
|
||||||
10000000 00000000
|
10000000 00000000
|
||||||
|
|
||||||
bit is set, bit is not set,
|
bit is set, bit is not set,
|
||||||
message is a message is an
|
message is a message is an
|
||||||
follow-on fragment initial I2NP message
|
follow-on fragment initial I2NP message
|
||||||
fragment or a complete fragment
|
fragment or a complete fragment
|
||||||
*/
|
*/
|
||||||
if (delivery_instructions[0] & 0x08) == 0x08 {
|
if (delivery_instructions[0] & 0x08) == 0x08 {
|
||||||
return FOLLOW_ON_FRAGMENT
|
return FOLLOW_ON_FRAGMENT
|
||||||
@ -176,83 +178,158 @@ func (delivery_instructions DeliveryInstructions) DeliveryType() byte {
|
|||||||
return (delivery_instructions[0] & 0x30) >> 4
|
return (delivery_instructions[0] & 0x30) >> 4
|
||||||
}
|
}
|
||||||
|
|
||||||
// do we have a delay factor?
|
// Check if the delay bit is set. This feature in unimplemented in the Java router.
|
||||||
func (di DeliveryInstructions) HasDelay() bool {
|
func (delivery_instructions DeliveryInstructions) HasDelay() bool {
|
||||||
return (di[0] & 0x10) == 0x10
|
/*
|
||||||
|
Check if the 4 bit of the Delivery Instructions
|
||||||
|
is set using binary AND operator to determine
|
||||||
|
if the Delivery Instructions has a delay
|
||||||
|
|
||||||
|
xxx1xxxx xxx0xxxx
|
||||||
|
&00010000 &00010000
|
||||||
|
--------- ---------
|
||||||
|
00010000 00000000
|
||||||
|
|
||||||
|
bit is set, bit is not set,
|
||||||
|
delay is included no delay included
|
||||||
|
|
||||||
|
Delay is unimplemented in the Java router, a warning
|
||||||
|
is logged as this is interesting behavior.
|
||||||
|
*/
|
||||||
|
delay := (delivery_instructions[0] & 0x10) == 0x10
|
||||||
|
if delay {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"at": "(DeliveryInstructions) HasDelay",
|
||||||
|
"info": "this feature is unimplemented in the Java router",
|
||||||
|
}).Warn("DeliveryInstructions found with delay bit set")
|
||||||
|
}
|
||||||
|
return delay
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns true if the Delivery Instructions are fragmented or false
|
||||||
|
// if the following data contains the entire message
|
||||||
|
func (delivery_instructions DeliveryInstructions) Fragmented() bool {
|
||||||
|
/*
|
||||||
|
Check if the 3 bit of the Delivery Instructions
|
||||||
|
is set using binary AND operator to determine
|
||||||
|
if the Delivery Instructions is fragmented or if
|
||||||
|
the entire message is contained in the following data
|
||||||
|
|
||||||
// get the tunnel id in this devilevery instrcutions or 0 if not applicable
|
xxxx1xxx xxxx0xxx
|
||||||
func (di DeliveryInstructions) TunnelID() (tid uint32) {
|
&00001000 &00001000
|
||||||
if di.DeliveryType() == DT_TUNNEL {
|
--------- ---------
|
||||||
// TODO(psi): what if this is 0?
|
00001000 00000000
|
||||||
tid = binary.BigEndian.Uint32(di[1:5])
|
|
||||||
|
bit is set, bit is not set,
|
||||||
|
message is message is not
|
||||||
|
fragmented fragmented
|
||||||
|
*/
|
||||||
|
return (delivery_instructions[0] & 0x08) == 0x08
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the extended options bit is set. This feature in unimplemented in the Java router.
|
||||||
|
func (delivery_instructions DeliveryInstructions) HasExtendedOptions() bool {
|
||||||
|
/*
|
||||||
|
Check if the 2 bit of the Delivery Instructions
|
||||||
|
is set using binary AND operator to determine
|
||||||
|
if the Delivery Instructions has a extended options
|
||||||
|
|
||||||
|
xxxxx1xx xxxxx0xx
|
||||||
|
&00000100 &00000100
|
||||||
|
--------- ---------
|
||||||
|
00000100 00000000
|
||||||
|
|
||||||
|
bit is set, bit is not set,
|
||||||
|
extended options extended options
|
||||||
|
included not included
|
||||||
|
|
||||||
|
Extended options is unimplemented in the Java router, a warning
|
||||||
|
is logged as this is interesting behavior.
|
||||||
|
*/
|
||||||
|
extended_options := (delivery_instructions[0] & 0x04) == 0x04
|
||||||
|
if extended_options {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"at": "(DeliveryInstructions) ExtendedOptions",
|
||||||
|
"info": "this feature is unimplemented in the Java router",
|
||||||
|
}).Warn("DeliveryInstructions found with extended_options bit set")
|
||||||
|
}
|
||||||
|
return extended_options
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the tunnel ID in this DeliveryInstructions or 0 and an error if the
|
||||||
|
// DeliveryInstructions are not of type DT_TUNNEL.
|
||||||
|
func (delivery_instructions DeliveryInstructions) TunnelID() (tunnel_id uint32, err error) {
|
||||||
|
if delivery_instructions.DeliveryType() == DT_TUNNEL {
|
||||||
|
tunnel_id = binary.BigEndian.Uint32(delivery_instructions[1:5])
|
||||||
|
} else {
|
||||||
|
err = errors.New("DeliveryInstructions are not of type DT_TUNNEL")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the hash for these DeliveryInstructions, which varies by hash type.
|
||||||
|
// If the type is DT_TUNNEL, hash is the SHA256 of the gateway router, if
|
||||||
|
// the type is DT_ROUTER it is the SHA256 of the router.
|
||||||
|
func (delivery_instructions DeliveryInstructions) ToHash() (hash common.Hash, err error) {
|
||||||
|
// TODO(hayden): check length of delivery instructions
|
||||||
|
delivery_type := delivery_instructions.DeliveryType()
|
||||||
|
if delivery_type == DT_TUNNEL {
|
||||||
|
copy(hash[:], delivery_instructions[1+4:33+4]) // 4 bytes for DT_TUNNEL's TunnelID
|
||||||
|
} else if delivery_type == DT_ROUTER {
|
||||||
|
copy(hash[:], delivery_instructions[1:33])
|
||||||
|
} else {
|
||||||
|
err = errors.New("No Hash on DeliveryInstructions not of type DT_TUNNEL or DT_ROUTER")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the delay factor if it exists
|
// get the delay factor if it exists
|
||||||
func (di DeliveryInstructions) Delay() (d DelayFactor) {
|
func (delivery_instructions DeliveryInstructions) Delay() (d DelayFactor) {
|
||||||
if di.HasDelay() {
|
if delivery_instructions.HasDelay() {
|
||||||
t := di.DeliveryType()
|
t := delivery_instructions.DeliveryType()
|
||||||
if t == DT_TUNNEL {
|
if t == DT_TUNNEL {
|
||||||
d = DelayFactor(di[37])
|
d = DelayFactor(delivery_instructions[37])
|
||||||
} else if t == DT_ROUTER {
|
} else if t == DT_ROUTER {
|
||||||
d = DelayFactor(di[36])
|
d = DelayFactor(delivery_instructions[36])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
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
|
// get the i2np message id or 0 if not applicable
|
||||||
func (di DeliveryInstructions) MessageID() (msgid uint32) {
|
func (delivery_instructions DeliveryInstructions) MessageID() (msgid uint32) {
|
||||||
if di.Type() == FOLLOW_ON_FRAGMENT {
|
if delivery_instructions.Type() == FOLLOW_ON_FRAGMENT {
|
||||||
idx := 1
|
idx := 1
|
||||||
t := di.DeliveryType()
|
t := delivery_instructions.DeliveryType()
|
||||||
if t == DT_TUNNEL {
|
if t == DT_TUNNEL {
|
||||||
idx += 36
|
idx += 36
|
||||||
} else if t == DT_ROUTER {
|
} else if t == DT_ROUTER {
|
||||||
idx += 32
|
idx += 32
|
||||||
}
|
}
|
||||||
if di.HasDelay() {
|
if delivery_instructions.HasDelay() {
|
||||||
idx++
|
idx++
|
||||||
}
|
}
|
||||||
msgid = binary.BigEndian.Uint32(di[idx:])
|
msgid = binary.BigEndian.Uint32(delivery_instructions[idx:])
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the size of the associated i2np fragment
|
// get the size of the associated i2np fragment
|
||||||
func (di DeliveryInstructions) FragmentSize() uint16 {
|
func (delivery_instructions DeliveryInstructions) FragmentSize() uint16 {
|
||||||
idx := 5
|
idx := 5
|
||||||
t := di.DeliveryType()
|
t := delivery_instructions.DeliveryType()
|
||||||
if t == DT_TUNNEL {
|
if t == DT_TUNNEL {
|
||||||
idx += 36
|
idx += 36
|
||||||
} else if t == DT_ROUTER {
|
} else if t == DT_ROUTER {
|
||||||
idx += 32
|
idx += 32
|
||||||
}
|
}
|
||||||
if di.HasDelay() {
|
if delivery_instructions.HasDelay() {
|
||||||
idx++
|
idx++
|
||||||
}
|
}
|
||||||
if di.HasExtendedOptions() {
|
if delivery_instructions.HasExtendedOptions() {
|
||||||
// add extended options length to idx
|
// add extended options length to idx
|
||||||
}
|
}
|
||||||
return binary.BigEndian.Uint16(di[idx:])
|
return binary.BigEndian.Uint16(delivery_instructions[idx:])
|
||||||
}
|
}
|
||||||
|
|
||||||
func readDeliveryInstructions(data []byte) (instructions DeliveryInstructions, remainder []byte, err error) {
|
func readDeliveryInstructions(data []byte) (instructions DeliveryInstructions, remainder []byte, err error) {
|
||||||
|
Reference in New Issue
Block a user