Files
sam3/config.go

440 lines
11 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
}
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
}
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
}
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
}
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
}
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 ""
}
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 ""
}
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)
}
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
}
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
}
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 "
}
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 ""
}
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
}
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
}
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
}
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
}
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
}
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
}
}
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 ""
}
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-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
}
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"
for _, o := range opts {
if err := o(&config); err != nil {
return nil, err
}
}
return &config, nil
}
2015-12-14 09:00:11 -05:00
// options map
type Options map[string]string
// obtain sam options as list of strings
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
}
// create new sam connector from config with a stream session
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
}
// create new sam datagram session from config
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
}