Separate out generate address function and make it's SAM port configurable

This commit is contained in:
eyedeekay
2024-11-29 18:01:00 -05:00
parent 40e34d7089
commit d8a31854b9
6 changed files with 212 additions and 215 deletions

View File

@ -7,13 +7,13 @@ import (
)
const (
// Address length constraints
MinAddressLength = 516
MaxAddressLength = 4096
// Domain suffixes
I2PDomainSuffix = ".i2p"
B32DomainSuffix = ".b32.i2p"
// Address length constraints
MinAddressLength = 516
MaxAddressLength = 4096
// Domain suffixes
I2PDomainSuffix = ".i2p"
B32DomainSuffix = ".b32.i2p"
)
// I2PAddr represents an I2P destination, equivalent to an IP address.
@ -22,98 +22,98 @@ type I2PAddr string
// Base64 returns the raw base64 representation of the I2P address.
func (a I2PAddr) Base64() string {
return string(a)
return string(a)
}
// String returns either the base64 or base32 representation based on configuration.
func (a I2PAddr) String() string {
if StringIsBase64 {
return a.Base64()
}
return a.Base32()
if StringIsBase64 {
return a.Base64()
}
return a.Base32()
}
// Network returns the network type, always "I2P".
func (a I2PAddr) Network() string {
return "I2P"
return "I2P"
}
// NewI2PAddrFromString creates a new I2P address from a base64-encoded string.
// It validates the format and returns an error if the address is invalid.
func NewI2PAddrFromString(addr string) (I2PAddr, error) {
addr = sanitizeAddress(addr)
if err := validateAddressFormat(addr); err != nil {
return I2PAddr(""), err
}
if err := validateBase64Encoding(addr); err != nil {
return I2PAddr(""), err
}
return I2PAddr(addr), nil
addr = sanitizeAddress(addr)
if err := validateAddressFormat(addr); err != nil {
return I2PAddr(""), err
}
if err := validateBase64Encoding(addr); err != nil {
return I2PAddr(""), err
}
return I2PAddr(addr), nil
}
func sanitizeAddress(addr string) string {
// Remove domain suffix if present
addr = strings.TrimSuffix(addr, I2PDomainSuffix)
return strings.Trim(addr, "\t\n\r\f ")
// Remove domain suffix if present
addr = strings.TrimSuffix(addr, I2PDomainSuffix)
return strings.Trim(addr, "\t\n\r\f ")
}
func validateAddressFormat(addr string) error {
if len(addr) > MaxAddressLength || len(addr) < MinAddressLength {
return fmt.Errorf("invalid address length: got %d, want between %d and %d",
len(addr), MinAddressLength, MaxAddressLength)
}
if strings.HasSuffix(addr, B32DomainSuffix) {
return fmt.Errorf("cannot convert %s to full destination", B32DomainSuffix)
}
return nil
if len(addr) > MaxAddressLength || len(addr) < MinAddressLength {
return fmt.Errorf("invalid address length: got %d, want between %d and %d",
len(addr), MinAddressLength, MaxAddressLength)
}
if strings.HasSuffix(addr, B32DomainSuffix) {
return fmt.Errorf("cannot convert %s to full destination", B32DomainSuffix)
}
return nil
}
func validateBase64Encoding(addr string) error {
buf := make([]byte, i2pB64enc.DecodedLen(len(addr)))
if _, err := i2pB64enc.Decode(buf, []byte(addr)); err != nil {
return fmt.Errorf("invalid base64 encoding: %w", err)
}
return nil
buf := make([]byte, i2pB64enc.DecodedLen(len(addr)))
if _, err := i2pB64enc.Decode(buf, []byte(addr)); err != nil {
return fmt.Errorf("invalid base64 encoding: %w", err)
}
return nil
}
// NewI2PAddrFromBytes creates a new I2P address from a byte array.
func NewI2PAddrFromBytes(addr []byte) (I2PAddr, error) {
if len(addr) > MaxAddressLength || len(addr) < MinAddressLength {
return I2PAddr(""), fmt.Errorf("invalid address length: got %d, want between %d and %d",
len(addr), MinAddressLength, MaxAddressLength)
}
encoded := make([]byte, i2pB64enc.EncodedLen(len(addr)))
i2pB64enc.Encode(encoded, addr)
return I2PAddr(encoded), nil
if len(addr) > MaxAddressLength || len(addr) < MinAddressLength {
return I2PAddr(""), fmt.Errorf("invalid address length: got %d, want between %d and %d",
len(addr), MinAddressLength, MaxAddressLength)
}
encoded := make([]byte, i2pB64enc.EncodedLen(len(addr)))
i2pB64enc.Encode(encoded, addr)
return I2PAddr(encoded), nil
}
// ToBytes converts the I2P address to its raw byte representation.
func (addr I2PAddr) ToBytes() ([]byte, error) {
decoded, err := i2pB64enc.DecodeString(string(addr))
if err != nil {
return nil, fmt.Errorf("decoding address: %w", err)
}
return decoded, nil
decoded, err := i2pB64enc.DecodeString(string(addr))
if err != nil {
return nil, fmt.Errorf("decoding address: %w", err)
}
return decoded, nil
}
// Base32 returns the *.b32.i2p representation of the address.
func (addr I2PAddr) Base32() string {
return addr.DestHash().String()
return addr.DestHash().String()
}
// DestHash computes the SHA-256 hash of the address.
func (addr I2PAddr) DestHash() I2PDestHash {
var hash I2PDestHash
h := sha256.New()
if bytes, err := addr.ToBytes(); err == nil {
h.Write(bytes)
copy(hash[:], h.Sum(nil))
}
return hash
}
var hash I2PDestHash
h := sha256.New()
if bytes, err := addr.ToBytes(); err == nil {
h.Write(bytes)
copy(hash[:], h.Sum(nil))
}
return hash
}