230 lines
5.8 KiB
Go
230 lines
5.8 KiB
Go
package sam3
|
|
|
|
import (
|
|
"fmt"
|
|
"math/rand"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
|
|
"github.com/go-i2p/i2pkeys"
|
|
"github.com/go-i2p/sam3/common"
|
|
"github.com/go-i2p/sam3/config"
|
|
)
|
|
|
|
const DEFAULT_LEASESET_TYPE = "i2cp.leaseSetEncType=4"
|
|
|
|
// I2PConfig is a struct which manages I2P configuration options
|
|
type I2PConfig struct {
|
|
common.SAMFormatter
|
|
config.SessionOptions
|
|
config.TransportOptions
|
|
config.TunnelOptions
|
|
config.EncryptedLeaseSetOptions
|
|
DestinationKeys i2pkeys.I2PKeys
|
|
|
|
// Streaming Library options
|
|
AccessListType string
|
|
AccessList []string
|
|
}
|
|
|
|
// Sam returns the SAM address in the form of "host:port"
|
|
func (f *I2PConfig) Sam() string {
|
|
host := "127.0.0.1"
|
|
port := "7656"
|
|
if f.SamHost != "" {
|
|
host = f.SamHost
|
|
}
|
|
if f.SamPort != "" {
|
|
port = f.SamPort
|
|
}
|
|
log.WithFields(logrus.Fields{
|
|
"host": host,
|
|
"port": port,
|
|
}).Debug("SAM address constructed")
|
|
return fmt.Sprintf("%s:%s", host, port)
|
|
}
|
|
|
|
// SetSAMAddress sets the SAM address from a string in the form of "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]
|
|
} else {
|
|
if f.SamHost == "" {
|
|
f.SamHost = "127.0.0.1"
|
|
}
|
|
if f.SamPort == "" {
|
|
f.SamPort = "7656"
|
|
}
|
|
}
|
|
log.WithFields(logrus.Fields{
|
|
"host": f.SamHost,
|
|
"port": f.SamPort,
|
|
}).Debug("SAM address set")
|
|
i2pkeys.DefaultSAMAddress = f.Sam()
|
|
}
|
|
|
|
// ID returns the tunnel name in the form of "ID=name"
|
|
func (f *I2PConfig) ID() string {
|
|
if f.NickName == "" {
|
|
b := make([]byte, 12)
|
|
for i := range b {
|
|
b[i] = "abcdefghijklmnopqrstuvwxyz"[rand.Intn(len("abcdefghijklmnopqrstuvwxyz"))]
|
|
}
|
|
f.NickName = string(b)
|
|
log.WithField("NickName", f.NickName).Debug("Generated random tunnel name")
|
|
}
|
|
return fmt.Sprintf(" ID=%s ", f.NickName)
|
|
}
|
|
|
|
// MinSAM returns the minimum SAM version required in major.minor form
|
|
func (f *I2PConfig) MinSAM() string {
|
|
min, _ := f.GetVersions()
|
|
return string(min)
|
|
}
|
|
|
|
// MaxSAM returns the maximum SAM version required in major.minor form
|
|
func (f *I2PConfig) MaxSAM() string {
|
|
_, max := f.GetVersions()
|
|
return string(max)
|
|
}
|
|
|
|
func (f *I2PConfig) GetVersions() (min, max common.ProtocolVersion) {
|
|
if f.SamMin == "" {
|
|
min = common.SAM31Version.String
|
|
} else {
|
|
min = common.ProtocolVersion(f.SamMin)
|
|
}
|
|
if f.SamMax == "" {
|
|
max = common.SAM33Version.String
|
|
log.Debug("Using default MaxSAM: 3.3")
|
|
} else {
|
|
max = common.ProtocolVersion(f.SamMax)
|
|
}
|
|
return min, max
|
|
}
|
|
|
|
// DestinationKey returns the destination key setting in the form of "DESTINATION=key"
|
|
func (f *I2PConfig) DestinationKey() string {
|
|
if &f.DestinationKeys != nil {
|
|
log.WithField("destinationKey", f.DestinationKeys.String()).Debug("Destination key set")
|
|
fmt.Sprintf(" DESTINATION=%s ", f.DestinationKeys.String())
|
|
}
|
|
log.Debug("Using TRANSIENT destination")
|
|
return " DESTINATION=TRANSIENT "
|
|
}
|
|
|
|
// Print returns the full config as a string
|
|
func (f *I2PConfig) Print() []string {
|
|
lsk, lspk, lspsk := f.Leasesetsettings()
|
|
return []string{
|
|
// f.targetForPort443(),
|
|
f.InboundLength(),
|
|
f.OutboundLength(),
|
|
f.InboundVariance(),
|
|
f.OutboundVariance(),
|
|
f.InboundBackupQuantity(),
|
|
f.OutboundBackupQuantity(),
|
|
f.InboundQuantity(),
|
|
f.OutboundQuantity(),
|
|
f.InboundDoZero(),
|
|
f.OutboundDoZero(),
|
|
//"i2cp.fastRecieve=" + f.FastRecieve,
|
|
f.DoFastReceive(),
|
|
f.UsesCompression(),
|
|
f.Reduce(),
|
|
f.Close(),
|
|
f.Reliability(),
|
|
f.EncryptLease(),
|
|
lsk, lspk, lspsk,
|
|
f.Accesslisttype(),
|
|
f.Accesslist(),
|
|
f.LeaseSetEncryptionType(),
|
|
}
|
|
}
|
|
|
|
// Accesslisttype returns the access list type
|
|
func (f *I2PConfig) Accesslisttype() string {
|
|
if f.AccessListType == "whitelist" {
|
|
log.Debug("Access list type set to whitelist")
|
|
return "i2cp.enableAccessList=true"
|
|
} else if f.AccessListType == "blacklist" {
|
|
log.Debug("Access list type set to blacklist")
|
|
return "i2cp.enableBlackList=true"
|
|
} else if f.AccessListType == "none" {
|
|
log.Debug("Access list type set to none")
|
|
return ""
|
|
}
|
|
log.Debug("Access list type not set")
|
|
return ""
|
|
}
|
|
|
|
// Accesslist returns the access list in the form of "i2cp.accessList=list"
|
|
func (f *I2PConfig) Accesslist() string {
|
|
if f.AccessListType != "" && len(f.AccessList) > 0 {
|
|
r := strings.Join(f.AccessList, ",")
|
|
log.WithField("accessList", r).Debug("Access list generated")
|
|
return fmt.Sprintf(" i2cp.accessList=%s ", r)
|
|
}
|
|
log.Debug("Access list not set")
|
|
return ""
|
|
}
|
|
|
|
// NewConfig returns a new config with default values or updates them with functional arguments
|
|
func NewConfig(opts ...func(*I2PConfig) error) (*I2PConfig, error) {
|
|
config := I2PConfig{
|
|
EncryptedLeaseSetOptions: config.EncryptedLeaseSetOptions{
|
|
EncryptLeaseSet: false,
|
|
LeaseSetKey: "",
|
|
LeaseSetPrivateKey: "",
|
|
LeaseSetPrivateSigningKey: "",
|
|
LeaseSetEncryption: DEFAULT_LEASESET_TYPE,
|
|
},
|
|
TunnelOptions: config.TunnelOptions{
|
|
InAllowZeroHop: false,
|
|
OutAllowZeroHop: false,
|
|
InLength: 3,
|
|
OutLength: 3,
|
|
InQuantity: 2,
|
|
OutQuantity: 2,
|
|
InVariance: 1,
|
|
OutVariance: 1,
|
|
InBackupQuantity: 3,
|
|
OutBackupQuantity: 3,
|
|
},
|
|
SessionOptions: config.SessionOptions{
|
|
NickName: "",
|
|
Style: "STREAM",
|
|
SigType: "EdDSA_SHA512_Ed25519",
|
|
InFromPort: "",
|
|
OutToPort: "",
|
|
Protocol: "",
|
|
UDPPort: 0,
|
|
SamHost: "127.0.0.1",
|
|
SamPort: "7656",
|
|
SamMin: string(common.SAM31Version.String),
|
|
SamMax: string(common.SAM33Version.String),
|
|
},
|
|
TransportOptions: config.TransportOptions{
|
|
UseCompression: "true",
|
|
FastReceive: "false",
|
|
MessageReliability: "none",
|
|
CloseIdleTimeout: 5 * time.Minute,
|
|
ReduceIdleQuantity: 1,
|
|
ReduceIdle: false,
|
|
CloseIdle: false,
|
|
},
|
|
}
|
|
for _, o := range opts {
|
|
if err := o(&config); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return &config, nil
|
|
}
|