Files
sam3/config.go

464 lines
13 KiB
Go
Raw Normal View History

2015-12-14 09:00:11 -05:00
package sam3
import (
2016-02-10 17:54:17 -05:00
"fmt"
2019-12-07 22:10:55 -05:00
"math/rand"
2016-02-10 17:54:17 -05:00
"net"
"strconv"
2019-12-07 22:09:40 -05:00
"strings"
"github.com/sirupsen/logrus"
2024-11-09 11:54:54 -05:00
"github.com/go-i2p/i2pkeys"
2015-12-14 09:00:11 -05:00
)
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
Fromport string
Toport string
2019-12-07 22:10:55 -05:00
Style string
TunType string
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
FastRecieve string
UseCompression string
MessageReliability string
CloseIdle string
CloseIdleTime string
ReduceIdle string
ReduceIdleTime string
ReduceIdleQuantity string
2024-01-07 12:09:13 -05:00
LeaseSetEncryption string
// 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")
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 {
if f.samMax() < 3.1 {
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 ""
}
if f.Fromport != "0" {
2024-10-15 12:23:24 -04:00
log.WithField("fromPort", f.Fromport).Debug("FromPort set")
2019-12-07 22:09:40 -05:00
return " FROM_PORT=" + f.Fromport + " "
}
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 {
if f.samMax() < 3.1 {
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 ""
}
if f.Toport != "0" {
2024-10-15 12:23:24 -04:00
log.WithField("toPort", f.Toport).Debug("ToPort set")
2019-12-07 22:09:40 -05:00
return " TO_PORT=" + f.Toport + " "
}
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 {
2019-12-07 22:10:55 -05:00
if f.Style != "" {
2024-10-15 12:23:24 -04:00
log.WithField("style", f.Style).Debug("Session style set")
2019-12-07 22:10:55 -05:00
return " STYLE=" + f.Style + " "
}
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-10-15 12:23:24 -04:00
log.Debug("Using default MinSAM: 3.0")
2019-12-07 22:09:40 -05:00
return "3.0"
}
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-10-15 12:23:24 -04:00
log.Debug("Using default MaxSAM: 3.1")
2019-12-07 22:09:40 -05:00
return "3.1"
}
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 {
if f.samMax() < 3.1 {
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 {
2019-12-07 22:10:55 -05:00
if f.MessageReliability != "" {
2024-10-15 12:23:24 -04:00
log.WithField("reliability", f.MessageReliability).Debug("Message reliability set")
2019-12-07 22:10:55 -05:00
return " i2cp.messageReliability=" + f.MessageReliability + " "
}
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,
"closeIdleTime": f.CloseIdleTime,
}).Debug("Close idle settings applied")
2019-12-07 22:09:40 -05:00
return "i2cp.closeOnIdle=" + f.CloseIdle + "i2cp.closeIdleTime=" + f.CloseIdleTime
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 + " "
}
if f.FastRecieve == "true" {
r += " " + f.FastRecieve + " "
}
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 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{
// 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,
"i2cp.gzip=" + f.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")
// 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
const DEFAULT_LEASESET_TYPE = "i2cp.leaseSetEncType=4"
// 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) {
var config I2PConfig
config.SamHost = "127.0.0.1"
config.SamPort = "7656"
config.SamMin = "3.0"
config.SamMax = "3.3"
2019-12-07 22:09:40 -05:00
config.TunName = ""
config.TunType = "server"
2019-12-07 22:10:55 -05:00
config.Style = "STREAM"
2019-12-07 22:09:40 -05:00
config.InLength = "3"
config.OutLength = "3"
config.InQuantity = "2"
config.OutQuantity = "2"
config.InVariance = "1"
config.OutVariance = "1"
config.InBackupQuantity = "3"
config.OutBackupQuantity = "3"
config.InAllowZeroHop = "false"
config.OutAllowZeroHop = "false"
config.EncryptLeaseSet = "false"
config.LeaseSetKey = ""
config.LeaseSetPrivateKey = ""
config.LeaseSetPrivateSigningKey = ""
config.FastRecieve = "false"
config.UseCompression = "true"
config.ReduceIdle = "false"
config.ReduceIdleTime = "15"
config.ReduceIdleQuantity = "4"
config.CloseIdle = "false"
config.CloseIdleTime = "300000"
config.MessageReliability = "none"
2024-11-22 20:35:39 -05:00
config.LeaseSetEncryption = DEFAULT_LEASESET_TYPE
2019-12-07 22:09:40 -05:00
for _, o := range opts {
if err := o(&config); err != nil {
return nil, err
}
}
return &config, nil
}
2024-11-22 20:35:39 -05:00
// Options a map of options
2015-12-14 09:00:11 -05:00
type Options map[string]string
2024-11-22 20:35:39 -05:00
// AsList obtain sam options as list of strings
2015-12-14 09:00:11 -05:00
func (opts Options) AsList() (ls []string) {
2016-02-10 17:54:17 -05:00
for k, v := range opts {
ls = append(ls, fmt.Sprintf("%s=%s", k, v))
}
return
2015-12-14 09:00:11 -05:00
}
// Config is the config type for the sam connector api for i2p which allows applications to 'speak' with i2p
type Config struct {
2016-02-10 17:54:17 -05:00
Addr string
Opts Options
Session string
Keyfile string
2015-12-14 09:00:11 -05:00
}
2024-11-22 20:35:39 -05:00
// StreamSession create new sam connector from config with a stream session
2015-12-14 09:00:11 -05:00
func (cfg *Config) StreamSession() (session *StreamSession, err error) {
2016-02-10 17:54:17 -05:00
// connect
var s *SAM
s, err = NewSAM(cfg.Addr)
if err == nil {
// ensure keys exist
var keys i2pkeys.I2PKeys
2016-02-10 17:54:17 -05:00
keys, err = s.EnsureKeyfile(cfg.Keyfile)
if err == nil {
// create session
session, err = s.NewStreamSession(cfg.Session, keys, cfg.Opts.AsList())
}
}
return
2015-12-14 09:00:11 -05:00
}
2024-11-22 20:35:39 -05:00
// DatagramSession create new sam datagram session from config
2015-12-14 09:00:11 -05:00
func (cfg *Config) DatagramSession() (session *DatagramSession, err error) {
2016-02-10 17:54:17 -05:00
// connect
var s *SAM
s, err = NewSAM(cfg.Addr)
if err == nil {
// ensure keys exist
var keys i2pkeys.I2PKeys
2016-02-10 17:54:17 -05:00
keys, err = s.EnsureKeyfile(cfg.Keyfile)
if err == nil {
// determine udp port
var portstr string
_, portstr, err = net.SplitHostPort(cfg.Addr)
if IgnorePortError(err) == nil {
2016-02-10 17:54:17 -05:00
var port int
port, err = strconv.Atoi(portstr)
if err == nil && port > 0 {
// udp port is 1 lower
port--
// create session
session, err = s.NewDatagramSession(cfg.Session, keys, cfg.Opts.AsList(), port)
}
}
}
}
return
2015-12-14 09:00:11 -05:00
}