2015-12-14 09:00:11 -05:00
package sam3
import (
2019-12-07 22:10:55 -05:00
"math/rand"
2016-02-10 17:54:17 -05:00
"strconv"
2019-12-07 22:09:40 -05:00
"strings"
2024-11-23 00:47:49 -05:00
"time"
2019-05-25 14:36:16 -04:00
2024-11-22 18:48:09 -05:00
"github.com/sirupsen/logrus"
2024-11-09 11:54:54 -05:00
"github.com/go-i2p/i2pkeys"
2024-11-29 21:07:26 -05:00
"github.com/go-i2p/sam3/common"
2015-12-14 09:00:11 -05:00
)
2024-11-23 00:47:49 -05:00
const DEFAULT_LEASESET_TYPE = "i2cp.leaseSetEncType=4"
type SessionOptions struct {
Style string
SignatureType string
FromPort string
ToPort string
Protocol string
UDPPort int
}
// Add transport options
type TransportOptions struct {
UseCompression string
FastReceive string
Reliability string
IdleTimeout time . Duration
}
2019-12-07 22:09:40 -05:00
// I2PConfig is a struct which manages I2P configuration options
type I2PConfig struct {
SamHost string
SamPort string
TunName string
SamMin string
SamMax string
2024-11-23 00:47:49 -05:00
SessionOptions
TransportOptions
2019-12-07 22:09:40 -05:00
2019-12-07 22:10:55 -05:00
DestinationKeys i2pkeys . I2PKeys
2019-12-07 22:09:40 -05:00
SigType string
EncryptLeaseSet string
LeaseSetKey string
LeaseSetPrivateKey string
LeaseSetPrivateSigningKey string
2019-12-07 22:10:55 -05:00
LeaseSetKeys i2pkeys . I2PKeys
2019-12-07 22:09:40 -05:00
InAllowZeroHop string
OutAllowZeroHop string
InLength string
OutLength string
InQuantity string
OutQuantity string
InVariance string
OutVariance string
InBackupQuantity string
OutBackupQuantity string
CloseIdle string
ReduceIdle string
ReduceIdleTime string
ReduceIdleQuantity string
2024-01-07 12:09:13 -05:00
LeaseSetEncryption string
2024-11-22 18:48:09 -05:00
// Streaming Library options
2019-12-07 22:09:40 -05:00
AccessListType string
AccessList [ ] string
}
2024-11-22 20:35:39 -05:00
// Sam returns the SAM address in the form of "host:port"
2019-12-07 22:09:40 -05:00
func ( f * I2PConfig ) Sam ( ) string {
host := "127.0.0.1"
port := "7656"
if f . SamHost != "" {
host = f . SamHost
}
if f . SamPort != "" {
port = f . SamPort
}
2024-10-15 12:23:24 -04:00
log . WithFields ( logrus . Fields {
"host" : host ,
"port" : port ,
} ) . Debug ( "SAM address constructed" )
2019-12-07 22:09:40 -05:00
return host + ":" + port
}
2024-11-22 20:35:39 -05:00
// SetSAMAddress sets the SAM address from a string in the form of "host:port"
2019-12-07 22:09:40 -05:00
func ( f * I2PConfig ) SetSAMAddress ( addr string ) {
hp := strings . Split ( addr , ":" )
if len ( hp ) == 1 {
f . SamHost = hp [ 0 ]
} else if len ( hp ) == 2 {
f . SamPort = hp [ 1 ]
f . SamHost = hp [ 0 ]
}
f . SamPort = "7656"
f . SamHost = "127.0.0.1"
2024-10-15 12:23:24 -04:00
log . WithFields ( logrus . Fields {
"host" : f . SamHost ,
"port" : f . SamPort ,
} ) . Debug ( "SAM address set" )
2024-11-29 21:07:26 -05:00
i2pkeys . DefaultSAMAddress = f . Sam ( )
2019-12-07 22:09:40 -05:00
}
2024-11-22 20:35:39 -05:00
// ID returns the tunnel name in the form of "ID=name"
2019-12-07 22:09:40 -05:00
func ( f * I2PConfig ) ID ( ) string {
if f . TunName == "" {
b := make ( [ ] byte , 12 )
2019-12-07 22:10:55 -05:00
for i := range b {
b [ i ] = "abcdefghijklmnopqrstuvwxyz" [ rand . Intn ( len ( "abcdefghijklmnopqrstuvwxyz" ) ) ]
}
f . TunName = string ( b )
2024-10-15 12:23:24 -04:00
log . WithField ( "TunName" , f . TunName ) . Debug ( "Generated random tunnel name" )
2019-12-07 22:09:40 -05:00
}
2019-12-07 22:10:55 -05:00
return " ID=" + f . TunName + " "
2019-12-07 22:09:40 -05:00
}
2024-11-22 20:35:39 -05:00
// Leasesetsettings returns the lease set settings in the form of "i2cp.leaseSetKey=key i2cp.leaseSetPrivateKey=key i2cp.leaseSetPrivateSigningKey=key"
2019-12-07 22:09:40 -05:00
func ( f * I2PConfig ) Leasesetsettings ( ) ( string , string , string ) {
var r , s , t string
if f . LeaseSetKey != "" {
r = " i2cp.leaseSetKey=" + f . LeaseSetKey + " "
}
if f . LeaseSetPrivateKey != "" {
s = " i2cp.leaseSetPrivateKey=" + f . LeaseSetPrivateKey + " "
}
if f . LeaseSetPrivateSigningKey != "" {
t = " i2cp.leaseSetPrivateSigningKey=" + f . LeaseSetPrivateSigningKey + " "
}
2024-10-15 12:23:24 -04:00
log . WithFields ( logrus . Fields {
"leaseSetKey" : r ,
"leaseSetPrivateKey" : s ,
"leaseSetPrivateSigningKey" : t ,
} ) . Debug ( "Lease set settings constructed" )
2019-12-07 22:09:40 -05:00
return r , s , t
}
2024-11-22 20:35:39 -05:00
// FromPort returns the from port setting in the form of "FROM_PORT=port"
2019-12-07 22:09:40 -05:00
func ( f * I2PConfig ) FromPort ( ) string {
2024-11-29 21:07:26 -05:00
if f . samMax ( ) < common . SAM31Version . Number {
2024-10-15 12:23:24 -04:00
log . Debug ( "SAM version < 3.1, FromPort not applicable" )
2019-12-07 22:09:40 -05:00
return ""
}
2024-11-23 00:47:49 -05:00
if f . SessionOptions . FromPort != "0" {
log . WithField ( "fromPort" , f . SessionOptions . FromPort ) . Debug ( "FromPort set" )
return " FROM_PORT=" + f . SessionOptions . FromPort + " "
2019-12-07 22:09:40 -05:00
}
2024-10-15 12:23:24 -04:00
log . Debug ( "FromPort not set" )
2019-12-07 22:09:40 -05:00
return ""
}
2024-11-22 20:35:39 -05:00
// ToPort returns the to port setting in the form of "TO_PORT=port"
2019-12-07 22:09:40 -05:00
func ( f * I2PConfig ) ToPort ( ) string {
2024-11-29 21:07:26 -05:00
if f . samMax ( ) < common . SAM31Version . Number {
2024-10-15 12:23:24 -04:00
log . Debug ( "SAM version < 3.1, ToPort not applicable" )
2019-12-07 22:09:40 -05:00
return ""
}
2024-11-23 00:47:49 -05:00
if f . SessionOptions . ToPort != "0" {
log . WithField ( "toPort" , f . SessionOptions . ToPort ) . Debug ( "ToPort set" )
return " TO_PORT=" + f . SessionOptions . ToPort + " "
2019-12-07 22:09:40 -05:00
}
2024-10-15 12:23:24 -04:00
log . Debug ( "ToPort not set" )
2019-12-07 22:09:40 -05:00
return ""
}
2024-11-22 20:35:39 -05:00
// SessionStyle returns the session style setting in the form of "STYLE=style"
2019-12-07 22:09:40 -05:00
func ( f * I2PConfig ) SessionStyle ( ) string {
2024-11-23 00:47:49 -05:00
if f . SessionOptions . Style != "" {
log . WithField ( "style" , f . SessionOptions . Style ) . Debug ( "Session style set" )
return " STYLE=" + f . SessionOptions . Style + " "
2019-12-07 22:10:55 -05:00
}
2024-10-15 12:23:24 -04:00
log . Debug ( "Using default STREAM style" )
2019-12-07 22:10:55 -05:00
return " STYLE=STREAM "
2019-12-07 22:09:40 -05:00
}
func ( f * I2PConfig ) samMax ( ) float64 {
i , err := strconv . Atoi ( f . SamMax )
if err != nil {
2024-10-15 12:23:24 -04:00
log . WithError ( err ) . Warn ( "Failed to parse SamMax, using default 3.1" )
2019-12-07 22:09:40 -05:00
return 3.1
}
2024-10-15 12:23:24 -04:00
log . WithField ( "samMax" , float64 ( i ) ) . Debug ( "SAM max version parsed" )
2019-12-07 22:09:40 -05:00
return float64 ( i )
}
2024-11-22 20:35:39 -05:00
// MinSAM returns the minimum SAM version required in major.minor form
2019-12-07 22:09:40 -05:00
func ( f * I2PConfig ) MinSAM ( ) string {
if f . SamMin == "" {
2024-11-23 00:47:49 -05:00
log . Debug ( "Using default MinSAM: 3.1" )
return "3.1"
2019-12-07 22:09:40 -05:00
}
2024-10-15 12:23:24 -04:00
log . WithField ( "minSAM" , f . SamMin ) . Debug ( "MinSAM set" )
2019-12-07 22:09:40 -05:00
return f . SamMin
}
2024-11-22 20:35:39 -05:00
// MaxSAM returns the maximum SAM version required in major.minor form
2019-12-07 22:09:40 -05:00
func ( f * I2PConfig ) MaxSAM ( ) string {
if f . SamMax == "" {
2024-11-23 00:47:49 -05:00
log . Debug ( "Using default MaxSAM: 3.3" )
return "3.3"
2019-12-07 22:09:40 -05:00
}
2024-10-15 12:23:24 -04:00
log . WithField ( "maxSAM" , f . SamMax ) . Debug ( "MaxSAM set" )
2019-12-07 22:09:40 -05:00
return f . SamMax
}
2024-11-22 20:35:39 -05:00
// DestinationKey returns the destination key setting in the form of "DESTINATION=key"
2019-12-07 22:09:40 -05:00
func ( f * I2PConfig ) DestinationKey ( ) string {
if & f . DestinationKeys != nil {
2024-10-15 12:23:24 -04:00
log . WithField ( "destinationKey" , f . DestinationKeys . String ( ) ) . Debug ( "Destination key set" )
2019-12-07 22:09:40 -05:00
return " DESTINATION=" + f . DestinationKeys . String ( ) + " "
}
2024-10-15 12:23:24 -04:00
log . Debug ( "Using TRANSIENT destination" )
2019-12-07 22:09:40 -05:00
return " DESTINATION=TRANSIENT "
}
2024-11-22 20:35:39 -05:00
// SignatureType returns the signature type setting in the form of "SIGNATURE_TYPE=type"
2019-12-07 22:09:40 -05:00
func ( f * I2PConfig ) SignatureType ( ) string {
2024-11-29 21:07:26 -05:00
if f . samMax ( ) < common . SAM31Version . Number {
2024-10-15 12:23:24 -04:00
log . Debug ( "SAM version < 3.1, SignatureType not applicable" )
2019-12-07 22:09:40 -05:00
return ""
}
if f . SigType != "" {
2024-10-15 12:23:24 -04:00
log . WithField ( "sigType" , f . SigType ) . Debug ( "Signature type set" )
2019-12-07 22:09:40 -05:00
return " SIGNATURE_TYPE=" + f . SigType + " "
}
2024-10-15 12:23:24 -04:00
log . Debug ( "Signature type not set" )
2019-12-07 22:09:40 -05:00
return ""
}
2024-11-22 20:35:39 -05:00
// EncryptLease returns the lease set encryption setting in the form of "i2cp.encryptLeaseSet=true"
2019-12-07 22:09:40 -05:00
func ( f * I2PConfig ) EncryptLease ( ) string {
2019-12-07 22:10:55 -05:00
if f . EncryptLeaseSet == "true" {
2024-10-15 12:23:24 -04:00
log . Debug ( "Lease set encryption enabled" )
2019-12-07 22:10:55 -05:00
return " i2cp.encryptLeaseSet=true "
}
2024-10-15 12:23:24 -04:00
log . Debug ( "Lease set encryption not enabled" )
2019-12-07 22:10:55 -05:00
return ""
2019-12-07 22:09:40 -05:00
}
2024-11-22 20:35:39 -05:00
// Reliability returns the message reliability setting in the form of "i2cp.messageReliability=reliability"
2019-12-07 22:09:40 -05:00
func ( f * I2PConfig ) Reliability ( ) string {
2024-11-23 00:47:49 -05:00
if f . TransportOptions . Reliability != "" {
log . WithField ( "reliability" , f . TransportOptions . Reliability ) . Debug ( "Message reliability set" )
return " i2cp.messageReliability=" + f . TransportOptions . Reliability + " "
2019-12-07 22:10:55 -05:00
}
2024-10-15 12:23:24 -04:00
log . Debug ( "Message reliability not set" )
2019-12-07 22:10:55 -05:00
return ""
2019-12-07 22:09:40 -05:00
}
2024-11-22 20:35:39 -05:00
// Reduce returns the reduce idle settings in the form of "i2cp.reduceOnIdle=true i2cp.reduceIdleTime=time i2cp.reduceQuantity=quantity"
2019-12-07 22:09:40 -05:00
func ( f * I2PConfig ) Reduce ( ) string {
2019-12-07 22:10:55 -05:00
if f . ReduceIdle == "true" {
2024-10-15 12:23:24 -04:00
log . WithFields ( logrus . Fields {
"reduceIdle" : f . ReduceIdle ,
"reduceIdleTime" : f . ReduceIdleTime ,
"reduceIdleQuantity" : f . ReduceIdleQuantity ,
} ) . Debug ( "Reduce idle settings applied" )
2019-12-07 22:10:55 -05:00
return "i2cp.reduceOnIdle=" + f . ReduceIdle + "i2cp.reduceIdleTime=" + f . ReduceIdleTime + "i2cp.reduceQuantity=" + f . ReduceIdleQuantity
}
2024-10-15 12:23:24 -04:00
log . Debug ( "Reduce idle settings not applied" )
2019-12-07 22:10:55 -05:00
return ""
2019-12-07 22:09:40 -05:00
}
2024-11-22 20:35:39 -05:00
// Close returns the close idle settings in the form of "i2cp.closeOnIdle=true i2cp.closeIdleTime=time"
2019-12-07 22:09:40 -05:00
func ( f * I2PConfig ) Close ( ) string {
2019-12-07 22:10:55 -05:00
if f . CloseIdle == "true" {
2024-10-15 12:23:24 -04:00
log . WithFields ( logrus . Fields {
"closeIdle" : f . CloseIdle ,
2024-11-23 00:47:49 -05:00
"closeIdleTime" : f . TransportOptions . IdleTimeout . String ( ) ,
2024-10-15 12:23:24 -04:00
} ) . Debug ( "Close idle settings applied" )
2024-11-23 00:47:49 -05:00
return "i2cp.closeOnIdle=" + f . CloseIdle + "i2cp.closeIdleTime=" + f . TransportOptions . IdleTimeout . String ( )
2019-12-07 22:10:55 -05:00
}
2024-10-15 12:23:24 -04:00
log . Debug ( "Close idle settings not applied" )
2019-12-07 22:10:55 -05:00
return ""
2019-12-07 22:09:40 -05:00
}
2024-11-22 20:35:39 -05:00
// DoZero returns the zero hop settings in the form of "inbound.allowZeroHop=true outbound.allowZeroHop=true fastRecieve=true"
2019-12-07 22:09:40 -05:00
func ( f * I2PConfig ) DoZero ( ) string {
2019-12-07 22:10:55 -05:00
r := ""
if f . InAllowZeroHop == "true" {
r += " inbound.allowZeroHop=" + f . InAllowZeroHop + " "
}
if f . OutAllowZeroHop == "true" {
r += " outbound.allowZeroHop= " + f . OutAllowZeroHop + " "
}
2024-11-23 00:47:49 -05:00
if f . TransportOptions . FastReceive == "true" {
r += " " + f . TransportOptions . FastReceive + " "
2019-12-07 22:10:55 -05:00
}
2024-10-15 12:23:24 -04:00
log . WithField ( "zeroHopSettings" , r ) . Debug ( "Zero hop settings applied" )
2019-12-07 22:10:55 -05:00
return r
2019-12-07 22:09:40 -05:00
}
2024-11-22 18:48:09 -05:00
2024-11-22 20:35:39 -05:00
// Print returns the full config as a string
2019-12-07 22:09:40 -05:00
func ( f * I2PConfig ) Print ( ) [ ] string {
lsk , lspk , lspsk := f . Leasesetsettings ( )
return [ ] string {
2024-11-22 18:48:09 -05:00
// f.targetForPort443(),
2019-12-07 22:09:40 -05:00
"inbound.length=" + f . InLength ,
"outbound.length=" + f . OutLength ,
"inbound.lengthVariance=" + f . InVariance ,
"outbound.lengthVariance=" + f . OutVariance ,
"inbound.backupQuantity=" + f . InBackupQuantity ,
"outbound.backupQuantity=" + f . OutBackupQuantity ,
"inbound.quantity=" + f . InQuantity ,
"outbound.quantity=" + f . OutQuantity ,
f . DoZero ( ) ,
//"i2cp.fastRecieve=" + f.FastRecieve,
2024-11-23 00:47:49 -05:00
"i2cp.gzip=" + f . TransportOptions . UseCompression ,
2019-12-07 22:10:55 -05:00
f . Reduce ( ) ,
f . Close ( ) ,
2019-12-07 22:09:40 -05:00
f . Reliability ( ) ,
f . EncryptLease ( ) ,
lsk , lspk , lspsk ,
f . Accesslisttype ( ) ,
f . Accesslist ( ) ,
2024-01-07 12:09:13 -05:00
f . LeaseSetEncryptionType ( ) ,
2019-12-07 22:09:40 -05:00
}
}
2024-11-22 20:35:39 -05:00
// Accesslisttype returns the access list type
2019-12-07 22:09:40 -05:00
func ( f * I2PConfig ) Accesslisttype ( ) string {
if f . AccessListType == "whitelist" {
2024-10-15 12:23:24 -04:00
log . Debug ( "Access list type set to whitelist" )
2019-12-07 22:09:40 -05:00
return "i2cp.enableAccessList=true"
} else if f . AccessListType == "blacklist" {
2024-10-15 12:23:24 -04:00
log . Debug ( "Access list type set to blacklist" )
2019-12-07 22:09:40 -05:00
return "i2cp.enableBlackList=true"
} else if f . AccessListType == "none" {
2024-10-15 12:23:24 -04:00
log . Debug ( "Access list type set to none" )
2019-12-07 22:09:40 -05:00
return ""
}
2024-10-15 12:23:24 -04:00
log . Debug ( "Access list type not set" )
2019-12-07 22:09:40 -05:00
return ""
}
2024-11-22 20:35:39 -05:00
// Accesslist returns the access list in the form of "i2cp.accessList=list"
2019-12-07 22:09:40 -05:00
func ( f * I2PConfig ) Accesslist ( ) string {
if f . AccessListType != "" && len ( f . AccessList ) > 0 {
r := ""
for _ , s := range f . AccessList {
r += s + ","
}
2024-10-15 12:23:24 -04:00
log . WithField ( "accessList" , r ) . Debug ( "Access list generated" )
2019-12-07 22:09:40 -05:00
return "i2cp.accessList=" + strings . TrimSuffix ( r , "," )
}
2024-10-15 12:23:24 -04:00
log . Debug ( "Access list not set" )
2019-12-07 22:09:40 -05:00
return ""
}
2024-11-22 20:35:39 -05:00
// LeaseSetEncryptionType returns the lease set encryption type in the form of "i2cp.leaseSetEncType=type"
2024-01-07 12:09:13 -05:00
func ( f * I2PConfig ) LeaseSetEncryptionType ( ) string {
if f . LeaseSetEncryption == "" {
2024-10-15 12:23:24 -04:00
log . Debug ( "Using default lease set encryption type: 4,0" )
2024-01-07 12:09:13 -05:00
return "i2cp.leaseSetEncType=4,0"
}
for _ , s := range strings . Split ( f . LeaseSetEncryption , "," ) {
if _ , err := strconv . Atoi ( s ) ; err != nil {
2024-10-15 12:23:24 -04:00
log . WithField ( "invalidType" , s ) . Panic ( "Invalid encrypted leaseSet type" )
2024-11-22 18:48:09 -05:00
// panic("Invalid encrypted leaseSet type: " + s)
2024-01-07 12:09:13 -05:00
}
}
2024-10-15 12:23:24 -04:00
log . WithField ( "leaseSetEncType" , f . LeaseSetEncryption ) . Debug ( "Lease set encryption type set" )
2024-01-07 12:09:13 -05:00
return "i2cp.leaseSetEncType=" + f . LeaseSetEncryption
}
2024-11-22 20:35:39 -05:00
// NewConfig returns a new config with default values or updates them with functional arguments
2019-12-07 22:09:40 -05:00
func NewConfig ( opts ... func ( * I2PConfig ) error ) ( * I2PConfig , error ) {
2024-11-23 00:47:49 -05:00
config := I2PConfig {
SamHost : "127.0.0.1" ,
SamPort : "7656" ,
SamMin : "3.0" ,
SamMax : "3.3" ,
TunName : "" ,
InLength : "3" ,
OutLength : "3" ,
InQuantity : "2" ,
OutQuantity : "2" ,
InVariance : "1" ,
OutVariance : "1" ,
InBackupQuantity : "3" ,
OutBackupQuantity : "3" ,
InAllowZeroHop : "false" ,
OutAllowZeroHop : "false" ,
EncryptLeaseSet : "false" ,
LeaseSetKey : "" ,
LeaseSetPrivateKey : "" ,
LeaseSetPrivateSigningKey : "" ,
ReduceIdle : "false" ,
ReduceIdleTime : "15" ,
ReduceIdleQuantity : "1" ,
CloseIdle : "false" ,
LeaseSetEncryption : DEFAULT_LEASESET_TYPE ,
SessionOptions : SessionOptions {
Style : "STREAM" ,
SignatureType : "EdDSA_SHA512_Ed25519" ,
FromPort : "" ,
ToPort : "" ,
Protocol : "" ,
UDPPort : 0 ,
} ,
TransportOptions : TransportOptions {
UseCompression : "true" ,
FastReceive : "false" ,
Reliability : "none" ,
IdleTimeout : 5 * time . Minute ,
} ,
}
2019-12-07 22:09:40 -05:00
for _ , o := range opts {
if err := o ( & config ) ; err != nil {
return nil , err
}
}
return & config , nil
}