add documentation for delivery instructions and explain functions
This commit is contained in:
@@ -4,6 +4,123 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
I2P First Fragment Delivery Instructions
|
||||||
|
https://geti2p.net/spec/tunnel-message#struct-tunnelmessagedeliveryinstructions
|
||||||
|
Accurate for version 0.9.11
|
||||||
|
|
||||||
|
+----+----+----+----+----+----+----+----+
|
||||||
|
|flag| Tunnel ID (opt) | |
|
||||||
|
+----+----+----+----+----+ +
|
||||||
|
| |
|
||||||
|
+ +
|
||||||
|
| To Hash (optional) |
|
||||||
|
+ +
|
||||||
|
| |
|
||||||
|
+ +--------------+
|
||||||
|
| |dly | Message
|
||||||
|
+----+----+----+----+----+----+----+----+
|
||||||
|
ID (opt) |extended opts (opt)| size |
|
||||||
|
+----+----+----+----+----+----+----+----+
|
||||||
|
|
||||||
|
flag ::
|
||||||
|
1 byte
|
||||||
|
Bit order: 76543210
|
||||||
|
bit 7: 0 to specify an initial fragment or an unfragmented message
|
||||||
|
bits 6-5: delivery type
|
||||||
|
0x0 = LOCAL
|
||||||
|
0x01 = TUNNEL
|
||||||
|
0x02 = ROUTER
|
||||||
|
0x03 = unused, invalid
|
||||||
|
Note: LOCAL is used for inbound tunnels only, unimplemented
|
||||||
|
for outbound tunnels
|
||||||
|
bit 4: delay included? Unimplemented, always 0
|
||||||
|
If 1, a delay byte is included
|
||||||
|
bit 3: fragmented? If 0, the message is not fragmented, what follows
|
||||||
|
is the entire message
|
||||||
|
If 1, the message is fragmented, and the
|
||||||
|
instructions contain a Message ID
|
||||||
|
bit 2: extended options? Unimplemented, always 0
|
||||||
|
If 1, extended options are included
|
||||||
|
bits 1-0: reserved, set to 0 for compatibility with future uses
|
||||||
|
|
||||||
|
Tunnel ID :: TunnelId
|
||||||
|
4 bytes
|
||||||
|
Optional, present if delivery type is TUNNEL
|
||||||
|
The destination tunnel ID
|
||||||
|
|
||||||
|
To Hash ::
|
||||||
|
32 bytes
|
||||||
|
Optional, present if delivery type is DESTINATION, ROUTER, or TUNNEL
|
||||||
|
If DESTINATION, the SHA256 Hash of the destination
|
||||||
|
If ROUTER, the SHA256 Hash of the router
|
||||||
|
If TUNNEL, the SHA256 Hash of the gateway router
|
||||||
|
|
||||||
|
Delay ::
|
||||||
|
1 byte
|
||||||
|
Optional, present if delay included flag is set
|
||||||
|
In tunnel messages: Unimplemented, never present; original
|
||||||
|
specification:
|
||||||
|
bit 7: type (0 = strict, 1 = randomized)
|
||||||
|
bits 6-0: delay exponent (2^value minutes)
|
||||||
|
|
||||||
|
Message ID ::
|
||||||
|
4 bytes
|
||||||
|
Optional, present if this message is the first of 2 or more fragments
|
||||||
|
(i.e. if the fragmented bit is 1)
|
||||||
|
An ID that uniquely identifies all fragments as belonging to a single
|
||||||
|
message (the current implementation uses I2NPMessageHeader.msg_id)
|
||||||
|
|
||||||
|
Extended Options ::
|
||||||
|
2 or more bytes
|
||||||
|
Optional, present if extend options flag is set
|
||||||
|
Unimplemented, never present; original specification:
|
||||||
|
One byte length and then that many bytes
|
||||||
|
|
||||||
|
size ::
|
||||||
|
2 bytes
|
||||||
|
The length of the fragment that follows
|
||||||
|
Valid values: 1 to approx. 960 in a tunnel message
|
||||||
|
|
||||||
|
Total length: Typical length is:
|
||||||
|
3 bytes for LOCAL delivery (tunnel message);
|
||||||
|
35 bytes for ROUTER / DESTINATION delivery or 39 bytes for TUNNEL
|
||||||
|
delivery (unfragmented tunnel message);
|
||||||
|
39 bytes for ROUTER delivery or 43 bytes for TUNNEL delivery (first
|
||||||
|
fragment)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
I2P Follow-on Fragment Delivery Instructions
|
||||||
|
https://geti2p.net/spec/tunnel-message#struct-tunnelmessagedeliveryinstructions
|
||||||
|
Accurate for version 0.9.11
|
||||||
|
|
||||||
|
----+----+----+----+----+----+----+
|
||||||
|
|frag| Message ID | size |
|
||||||
|
+----+----+----+----+----+----+----+
|
||||||
|
|
||||||
|
frag ::
|
||||||
|
1 byte
|
||||||
|
Bit order: 76543210
|
||||||
|
binary 1nnnnnnd
|
||||||
|
bit 7: 1 to indicate this is a follow-on fragment
|
||||||
|
bits 6-1: nnnnnn is the 6 bit fragment number from 1 to 63
|
||||||
|
bit 0: d is 1 to indicate the last fragment, 0 otherwise
|
||||||
|
|
||||||
|
Message ID ::
|
||||||
|
4 bytes
|
||||||
|
Identifies the fragment sequence that this fragment belongs to.
|
||||||
|
This will match the message ID of an initial fragment (a fragment
|
||||||
|
with flag bit 7 set to 0 and flag bit 3 set to 1).
|
||||||
|
|
||||||
|
size ::
|
||||||
|
2 bytes
|
||||||
|
the length of the fragment that follows
|
||||||
|
valid values: 1 to 996
|
||||||
|
|
||||||
|
total length: 7 bytes
|
||||||
|
*/
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DT_LOCAL = iota
|
DT_LOCAL = iota
|
||||||
DT_TUNNEL
|
DT_TUNNEL
|
||||||
@@ -11,18 +128,57 @@ const (
|
|||||||
DT_UNUSED
|
DT_UNUSED
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
FIRST_FRAGMENT = iota
|
||||||
|
FOLLOW_ON_FRAGMENT
|
||||||
|
)
|
||||||
|
|
||||||
type DelayFactor byte
|
type DelayFactor byte
|
||||||
|
|
||||||
type DeliveryInstructions []byte
|
type DeliveryInstructions []byte
|
||||||
|
|
||||||
func (di DeliveryInstructions) DeliveryType() byte {
|
// Return if the DeliveryInstructions are of type FIRST_FRAGMENT or FOLLOW_ON_FRAGMENT.
|
||||||
return (di[0] & 0x30) >> 4
|
func (delivery_instructions DeliveryInstructions) Type() bool {
|
||||||
|
/*
|
||||||
|
Check if the 7 bit of the Delivery Instructions
|
||||||
|
is set using binary AND operator to determine
|
||||||
|
the Delivery Instructions type
|
||||||
|
|
||||||
|
1xxxxxxx 0xxxxxxx
|
||||||
|
&10000000 &10000000
|
||||||
|
--------- ---------
|
||||||
|
10000000 00000000
|
||||||
|
|
||||||
|
bit is set, bit is not set,
|
||||||
|
message is a message is an
|
||||||
|
follow-on fragment initial I2NP message
|
||||||
|
fragment or a complete fragment
|
||||||
|
*/
|
||||||
|
return (delivery_instructions[0] & 0x08) == 0x08
|
||||||
}
|
}
|
||||||
|
|
||||||
func (di DeliveryInstructions) IsFragmented() bool {
|
// Return the delivery type for these DeliveryInstructions, can be of type
|
||||||
return (di[0] & 0x08) == 0x08
|
// DT_LOCAL, DT_TUNNEL, DT_ROUTER, or DT_UNUSED.
|
||||||
|
func (delivery_instructions DeliveryInstructions) DeliveryType() byte {
|
||||||
|
/*
|
||||||
|
Check if the 6-5 bits of the Delivery Instructions
|
||||||
|
are set using binary AND operator to determine
|
||||||
|
the delivery type
|
||||||
|
|
||||||
|
xx0?xxxx
|
||||||
|
&00110000 bit shift
|
||||||
|
---------
|
||||||
|
000?0000 >> 4 => n (DT_* consts)
|
||||||
|
*/
|
||||||
|
return (delivery_instructions[0] & 0x30) >> 4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// do we have a delay factor?
|
||||||
|
func (di DeliveryInstructions) HasDelay() bool {
|
||||||
|
return (di[0] & 0x10) == 0x10
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// get the tunnel id in this devilevery instrcutions or 0 if not applicable
|
// get the tunnel id in this devilevery instrcutions or 0 if not applicable
|
||||||
func (di DeliveryInstructions) TunnelID() (tid uint32) {
|
func (di DeliveryInstructions) TunnelID() (tid uint32) {
|
||||||
if di.DeliveryType() == DT_TUNNEL {
|
if di.DeliveryType() == DT_TUNNEL {
|
||||||
@@ -32,11 +188,6 @@ func (di DeliveryInstructions) TunnelID() (tid uint32) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// do we have a delay factor?
|
|
||||||
func (di DeliveryInstructions) HasDelay() bool {
|
|
||||||
return (di[0] & 0x10) == 0x10
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the delay factor if it exists
|
// get the delay factor if it exists
|
||||||
func (di DeliveryInstructions) Delay() (d DelayFactor) {
|
func (di DeliveryInstructions) Delay() (d DelayFactor) {
|
||||||
if di.HasDelay() {
|
if di.HasDelay() {
|
||||||
|
Reference in New Issue
Block a user