Documentation
¶
Overview ¶
Package lease implements the I2P Lease and Lease2 common data structures according to specification version 0.9.67.
A Lease defines the authorization for a particular tunnel to receive messages targeting a Destination. Each lease contains the SHA256 hash of the RouterIdentity of the gateway router, the tunnel identifier, and an expiration date that determines when the lease becomes invalid for message delivery.
Two variants are supported:
Lease: 44-byte structure with 8-byte millisecond-precision timestamps. Used in the original LeaseSet structure.
Lease2: 40-byte structure with 4-byte second-precision timestamps. Introduced in specification 0.9.38 for LeaseSet2, EncryptedLeaseSet, and MetaLeaseSet structures.
Wire format (Lease, 44 bytes):
+----+----+----+----+----+----+----+----+ | tunnel_gw (32 bytes) | +----+----+----+----+----+----+----+----+ | tunnel_id (4) | end_date (8) | +----+----+----+----+----+----+----+----+
Wire format (Lease2, 40 bytes):
+----+----+----+----+----+----+----+----+ | tunnel_gw (32 bytes) | +----+----+----+----+----+----+----+----+ | tunnel_id (4) | end_date (4) | +----+----+----+----+----+----+----+----+
Constructors (NewLease, NewLease2) accept arbitrary timestamps and gateway hashes, including zero hashes and past times. Use Validate() or IsExpired() for semantic checks after construction. Parsing functions (ReadLease, ReadLease2) similarly perform no semantic validation, only structural parsing.
Spec reference: https://geti2p.net/spec/common-structures#lease
Index ¶
- Constants
- Variables
- type Lease
- func (lease Lease) Bytes() []byte
- func (lease Lease) Date() (date data.Date)
- func (lease Lease) Equal(other Lease) bool
- func (lease Lease) IsExpired() bool
- func (lease Lease) String() string
- func (lease Lease) Time() time.Time
- func (lease Lease) TunnelGateway() (hash data.Hash)
- func (lease Lease) TunnelID() uint32
- func (lease Lease) Validate() error
- type Lease2
- func (lease2 Lease2) Bytes() []byte
- func (lease2 Lease2) Date() (date data.Date)
- func (lease2 Lease2) EndDate() uint32
- func (lease2 Lease2) Equal(other Lease2) bool
- func (lease2 Lease2) IsExpired() bool
- func (lease2 Lease2) String() string
- func (lease2 Lease2) Time() time.Time
- func (lease2 Lease2) TunnelGateway() (hash data.Hash)
- func (lease2 Lease2) TunnelID() uint32
- func (lease2 Lease2) Validate() error
Constants ¶
const ( // LEASE_SIZE defines the total size of a complete I2P Lease structure in bytes. // A Lease consists of 32 bytes for tunnel gateway hash, 4 bytes for tunnel ID, and 8 bytes for end date. // This constant ensures consistent memory allocation and parsing across the I2P network. LEASE_SIZE = 44 // LEASE_TUNNEL_GW_SIZE defines the size of the tunnel gateway hash field in bytes. // This field contains the SHA256 hash of the RouterIdentity of the gateway router, // providing secure identification of the tunnel endpoint for message routing. LEASE_TUNNEL_GW_SIZE = 32 // LEASE_TUNNEL_ID_SIZE defines the size of the tunnel identifier field in bytes. // The tunnel ID is a 32-bit unsigned integer that uniquely identifies a specific tunnel // within the context of the gateway router for message forwarding. LEASE_TUNNEL_ID_SIZE = 4 // LEASE_END_DATE_SIZE defines the size of the end date field in legacy Lease structures. // Legacy Lease uses 8-byte millisecond timestamps (I2P Date format) for expiration, // providing nanosecond-resolution dates at the cost of 4 extra bytes compared to Lease2. LEASE_END_DATE_SIZE = 8 // LEASE2_SIZE defines the total size of a complete I2P Lease2 structure in bytes. // A Lease2 is a more compact version introduced in I2P specification 0.9.38 for LeaseSet2. // It consists of 32 bytes for tunnel gateway hash, 4 bytes for tunnel ID, and 4 bytes for end date. // This reduces the size from 44 bytes (Lease) to 40 bytes by using a 4-byte timestamp instead of 8-byte. LEASE2_SIZE = 40 // LEASE2_END_DATE_SIZE defines the size of the end date field in Lease2 structures. // Unlike legacy Lease which uses 8-byte millisecond timestamps, Lease2 uses 4-byte second timestamps // for more efficient encoding in LeaseSet2 structures introduced in I2P specification 0.9.38. LEASE2_END_DATE_SIZE = 4 // LEASE2_MAX_END_DATE is the maximum value for a Lease2 end_date field (uint32 max). // Corresponds to 2106-02-07T06:28:15 UTC. LEASE2_MAX_END_DATE = uint64(1<<32 - 1) )
Sizes in bytes of various components of a Lease according to I2P specification version 0.9.67
Variables ¶
var ( // ErrExpiredLease indicates a lease with an expiration time in the past. // Returned by Validate() when the lease has expired. ErrExpiredLease = errors.New("lease has expired") // ErrZeroGatewayHash indicates a lease with an all-zero tunnel gateway hash. // Returned by Validate() when the gateway hash is all zeros. ErrZeroGatewayHash = errors.New("tunnel gateway hash is zero") // ErrTimestampOverflow indicates a Lease2 expiration time exceeds the uint32 second range. // Lease2 uses 4-byte timestamps which overflow after 2106-02-07T06:28:15 UTC. ErrTimestampOverflow = errors.New("timestamp exceeds Lease2 uint32 range") // ErrPreEpochTimestamp indicates an expiration time before the Unix epoch (1970-01-01). // I2P timestamps are unsigned milliseconds/seconds since epoch; pre-epoch values // would wrap to extremely large unsigned values on the wire. ErrPreEpochTimestamp = errors.New("expiration time is before Unix epoch") // ErrNullDate indicates a lease with end_date = 0, which the I2P spec defines as // "undefined or null" (Date type definition). Distinct from ErrExpiredLease so // callers can handle null-date leases differently from merely-expired ones. ErrNullDate = errors.New("lease end_date is null (zero per I2P spec Date definition)") // ErrZeroTunnelID indicates a lease with tunnel ID 0. // The I2P spec states: "A Tunnel ID is generally greater than zero; // do not use a value of zero except in special cases." // Returned as an advisory by Validate(). ErrZeroTunnelID = errors.New("tunnel ID is zero (spec recommends non-zero except in special cases)") )
Errors
Functions ¶
This section is empty.
Types ¶
type Lease ¶
type Lease [LEASE_SIZE]byte
Lease is the representation of an I2P Lease.
https://geti2p.net/spec/common-structures#lease
func NewLease ¶
NewLease creates a new Lease with the provided tunnel gateway, tunnel ID, and expiration time.
This function constructs a properly formatted I2P Lease structure according to the specification, encoding the tunnel gateway hash, tunnel ID as big-endian uint32, and expiration time as milliseconds since epoch. No semantic validation is performed on the inputs; use Validate() to check for expired leases, zero gateway hashes, or other semantic issues.
Parameters:
- tunnelGateway: SHA256 hash of the RouterIdentity of the gateway router (32 bytes)
- tunnelID: Unsigned 32-bit tunnel identifier unique within the gateway router
- expirationTime: Time when the lease expires
Returns:
- *Lease: Pointer to the created 44-byte lease structure
- error: Currently always nil (reserved for future structural validation)
Example:
gatewayHash, _ := data.NewHashFromSlice(gatewayBytes)
expiration := time.Now().Add(10 * time.Minute)
lease, err := NewLease(gatewayHash, 12345, expiration)
if err != nil {
log.Fatal(err)
}
func NewLeaseFromBytes ¶
NewLeaseFromBytes creates a new Lease pointer from raw byte data using ReadLease. This convenience function wraps ReadLease to return a pointer to the parsed Lease structure instead of a value copy, which is useful for APIs that expect lease pointers.
On error, returns (nil, remainder, err). The remainder is returned even on failure to allow callers to skip past malformed data in a stream. If err != nil, the remainder contains all bytes beyond those that were expected to form the Lease (i.e., data itself if it was too short). Callers should not rely on remainder contents when err != nil unless they are implementing stream recovery logic.
func ReadLease ¶
ReadLease parses a Lease structure from raw byte data according to I2P specification. Validates that the input data contains at least 44 bytes required for a complete lease, then extracts the tunnel gateway hash, tunnel ID, and expiration date into a Lease structure. Returns the parsed lease, any remaining unparsed bytes, and an error if parsing fails.
func (Lease) Bytes ¶ added in v0.1.5
Bytes returns the complete Lease structure as a byte slice. This method enables serialization for network transmission or storage, providing API parity with Lease2.Bytes().
func (Lease) Date ¶
Date returns the expiration date of the lease as an I2P Date structure. Extracts the last 8 bytes of the lease structure which contain the expiration timestamp in milliseconds since Unix epoch. This date determines when the lease becomes invalid and can no longer be used for tunnel message delivery within the I2P network.
func (Lease) Equal ¶ added in v0.1.5
Equal returns true if two Lease structures are byte-for-byte identical.
func (Lease) IsExpired ¶ added in v0.1.5
IsExpired returns true if the lease's expiration time is before the current time.
func (Lease) String ¶ added in v0.1.5
String returns a human-readable representation of the Lease for debugging and logging.
func (Lease) Time ¶ added in v0.1.5
Time returns the expiration time as a Go time.Time value for convenient time operations. Uses unsigned decoding with a math.MaxInt64 cap: values above math.MaxInt64 are clamped to time.UnixMilli(math.MaxInt64) rather than wrapping to a pre-epoch time via signed cast.
Note: For millis > math.MaxInt64 (high bit set), Time() returns the clamped maximum while Date().Time() returns the zero time.Time{}. Both handle the edge case safely, but callers choosing between the two methods should be aware of this divergence.
func (Lease) TunnelGateway ¶
TunnelGateway returns the tunnel gateway hash from the lease structure. Extracts the first 32 bytes of the lease which contain the SHA256 hash of the RouterIdentity of the gateway router responsible for handling messages sent through this tunnel. The returned hash can be used to identify and route messages to the appropriate tunnel gateway.
func (Lease) TunnelID ¶
TunnelID returns the tunnel identifier as a 32-bit unsigned integer. Extracts bytes 32-35 of the lease structure and converts them from big-endian format to a native uint32 value. This ID uniquely identifies the specific tunnel within the context of the gateway router and is used for message routing and delivery.
func (Lease) Validate ¶ added in v0.1.5
Validate performs semantic validation on the lease. Returns a combined error (via errors.Join) if multiple issues are found: zero gateway hash, zero tunnel ID (advisory per spec), null end_date (per spec "Date == 0 is undefined or null"), or expired lease. Use errors.Is to check for specific error conditions. This is separate from construction to allow representing arbitrary wire-format data.
type Lease2 ¶ added in v0.0.3
type Lease2 [LEASE2_SIZE]byte
Lease2 is the representation of an I2P Lease2 structure. Lease2 is a compact version of Lease introduced in specification 0.9.38 for LeaseSet2. It uses 4-byte second timestamps instead of 8-byte millisecond timestamps for efficiency.
https://geti2p.net/spec/common-structures#lease2
func NewLease2 ¶ added in v0.0.3
NewLease2 creates a new Lease2 with the provided tunnel gateway, tunnel ID, and expiration time.
This function constructs a properly formatted I2P Lease2 structure according to specification 0.9.38, encoding the tunnel gateway hash, tunnel ID as big-endian uint32, and expiration time as seconds since epoch. Lease2 is a more compact version of Lease (40 bytes vs 44 bytes) used in LeaseSet2. No semantic validation is performed on gateway hash or time direction; use Validate() for that.
Parameters:
- tunnelGateway: SHA256 hash of the RouterIdentity of the gateway router (32 bytes)
- tunnelID: Unsigned 32-bit tunnel identifier unique within the gateway router
- expirationTime: Time when the lease expires
Returns:
- *Lease2: Pointer to the created 40-byte lease2 structure
- error: ErrTimestampOverflow if the time exceeds the uint32 second range (after 2106-02-07)
Note: Lease2 uses 4-byte timestamps representing seconds since Unix epoch, providing sufficient range until year 2106 while saving 4 bytes compared to the legacy Lease structure.
Example:
gatewayHash, _ := data.NewHashFromSlice(gatewayBytes)
expiration := time.Now().Add(10 * time.Minute)
lease2, err := NewLease2(gatewayHash, 12345, expiration)
if err != nil {
log.Fatal(err)
}
func NewLease2FromBytes ¶ added in v0.0.3
NewLease2FromBytes creates a new Lease2 pointer from raw byte data using ReadLease2. This convenience function wraps ReadLease2 to return a pointer to the parsed Lease2 structure instead of a value copy, which is useful for APIs that expect lease pointers.
On error, returns (nil, remainder, err). The remainder is returned even on failure to allow callers to skip past malformed data in a stream. If err != nil, the remainder contains all bytes beyond those that were expected to form the Lease2 (i.e., data itself if it was too short). Callers should not rely on remainder contents when err != nil unless they are implementing stream recovery logic.
Example: lease2Ptr, remainder, err := NewLease2FromBytes(networkData)
func ReadLease2 ¶ added in v0.0.3
ReadLease2 parses a Lease2 structure from raw byte data according to I2P specification 0.9.67. Validates that the input data contains at least 40 bytes required for a complete Lease2, then extracts the tunnel gateway hash, tunnel ID, and 4-byte expiration timestamp. Returns the parsed Lease2, any remaining unparsed bytes, and an error if parsing fails.
Example: lease2, remainder, err := ReadLease2(networkData)
func (Lease2) Bytes ¶ added in v0.0.3
Bytes returns the complete Lease2 structure as a byte slice. This method enables serialization for network transmission or storage.
func (Lease2) Date ¶ added in v0.1.5
Date returns the expiration as an I2P Date for API symmetry with Lease.Date(). The 4-byte seconds timestamp is converted to an 8-byte millisecond Date.
func (Lease2) EndDate ¶ added in v0.0.3
EndDate returns the expiration timestamp of the lease2 as a 32-bit unsigned integer. The timestamp represents seconds since Unix epoch (January 1, 1970 00:00:00 UTC). This is more compact than the legacy Lease which uses 8-byte millisecond timestamps, providing sufficient range until year 2106 while reducing structure size.
func (Lease2) Equal ¶ added in v0.1.5
Equal returns true if two Lease2 structures are byte-for-byte identical.
func (Lease2) IsExpired ¶ added in v0.1.5
IsExpired returns true if the lease2's expiration time is before the current time.
func (Lease2) String ¶ added in v0.1.5
String returns a human-readable representation of the Lease2 for debugging and logging.
func (Lease2) Time ¶ added in v0.0.3
Time returns the expiration time as a Go time.Time value for convenient time operations. Converts the 4-byte second timestamp to a time.Time in the UTC timezone. This method enables easy time comparisons, formatting, and duration calculations.
func (Lease2) TunnelGateway ¶ added in v0.0.3
TunnelGateway returns the tunnel gateway hash from the lease2 structure. Extracts the first 32 bytes of the lease2 which contain the SHA256 hash of the RouterIdentity of the gateway router responsible for handling messages sent through this tunnel. The returned hash can be used to identify and route messages to the appropriate tunnel gateway.
func (Lease2) TunnelID ¶ added in v0.0.3
TunnelID returns the tunnel identifier as a 32-bit unsigned integer. Extracts bytes 32-35 of the lease2 structure and converts them from big-endian format to a native uint32 value. This ID uniquely identifies the specific tunnel within the context of the gateway router and is used for message routing and delivery.
func (Lease2) Validate ¶ added in v0.1.5
Validate performs semantic validation on the lease2. Returns a combined error (via errors.Join) if multiple issues are found: zero gateway hash, zero tunnel ID (advisory per spec), null end_date (per spec "Date == 0 is undefined or null"), or expired lease. Use errors.Is to check for specific error conditions. This is separate from construction to allow representing arbitrary wire-format data.