51 Commits

Author SHA1 Message Date
idk
7048131842 Add the TLS Configuration to the configuration generator 2021-02-28 16:17:29 -05:00
idk
b47b3971f7 Add the TLS Configuration to the configuration generator 2021-02-28 16:16:30 -05:00
idk
e31a7636d0 tweak TLS configuration options 2021-02-28 16:10:55 -05:00
idk
9b05750814 TLS Certificate generation helper 2021-02-28 15:28:53 -05:00
idk
494f0274ba Add TLS Options 2021-02-28 14:54:48 -05:00
idk
a079a9c9ff Get ready for using a proper template 2021-02-28 14:19:46 -05:00
idk
fa15eeec97 Update default tunnels.ini 2021-02-28 13:39:04 -05:00
idk
d5422aee75 ditch the old interface options that never worked and weren't actually in the best place anyway 2021-02-28 13:20:32 -05:00
idk
4232b6e197 use interface options across all base tunnel types 2021-02-28 13:17:13 -05:00
idk
fcdd8b7f52 Start work on supporting TLS for tunnels, begin by switching all optional args to the interface instead of the concrete type 2021-02-28 12:34:22 -05:00
idk
529a5f77cb fix output of conf.Print 2021-02-05 21:58:30 -05:00
idk
8be5dfbee0 set enough defaults to validate new config 2020-09-20 16:58:04 -04:00
idk
87e663ed3d set enough defaults to validate new config 2020-09-20 16:48:04 -04:00
idk
ff11aeebc4 set enough defaults to validate new config 2020-09-20 16:42:24 -04:00
idk
8e0af0c4f6 add support for the config file 2020-09-19 23:21:56 -04:00
idk
3ab932c170 Fix error in config directory 2020-01-05 13:51:07 -05:00
idk
6159dc47f0 Fix error in config directory 2020-01-05 13:48:30 -05:00
idk
bf6b920eff add go.mod 2019-12-31 21:57:35 -05:00
idk
aa52be69ff remove vendor dir 2019-10-21 13:53:41 -04:00
idk
d2f767dbe0 clean up conditional compilation 2019-09-28 00:10:36 -04:00
idk
b89d62e481 update the manager to include noui 2019-09-27 23:45:37 -04:00
idk
06113918ea update the manager to include noui 2019-09-27 23:31:32 -04:00
idk
a884fa4692 update the manager to include noui 2019-09-27 23:29:17 -04:00
idk
fc36f9cf6f fix go vet for ./interface 2019-09-11 23:18:29 -04:00
idk
3248dd789d fix go vet for ./interface 2019-09-11 23:12:33 -04:00
idk
71ca8cd65f add in http outproxy helpers 2019-09-08 17:01:05 -04:00
idk
60e9f15b18 add in the outproxy helpers 2019-09-08 16:20:30 -04:00
idk
ee8617deb0 fix helpers 2019-09-06 16:43:33 -04:00
idk
029317222e bandwidth limits for TCP 2019-09-05 17:26:04 -04:00
idk
bcd32aa8ad bandwidth limits for TCP 2019-09-05 17:25:46 -04:00
idk
3c1a44e1d2 only limit if bytelimit > 0 2019-09-05 02:08:31 -04:00
idk
7167ba3a1c add per-client bandwidth limiter 2019-09-05 01:54:28 -04:00
idk
3ff494c374 add per-client bandwidth limiter 2019-09-05 01:45:17 -04:00
idk
aebbe18f3b bump version 2019-09-02 20:49:55 -04:00
idk
081b25d54c re-add noui version 2019-09-02 20:46:17 -04:00
idk
78306cc9e6 give more information when saving a key, like the name 2019-09-01 23:48:16 -04:00
idk
0e40939f7d ssure that a config file exists even if null 2019-09-01 21:23:00 -04:00
idk
ccc29b5e66 purge redundant config items! 2019-08-31 16:55:22 -04:00
idk
36655256c3 fix client control panel in webui 2019-08-31 15:12:08 -04:00
idk
efccedaafb next part of the migration to a single standardized config struct 2019-08-31 13:22:32 -04:00
idk
a75baf9db7 next part of the migration to a single standardized config struct 2019-08-31 13:22:12 -04:00
idk
d67c0c0e31 move the helpers 2019-08-31 03:12:54 -04:00
idk
e88e3a0a6b move the helpers 2019-08-31 03:12:09 -04:00
idk
f530ccd37f Fix the helpers 2019-08-31 03:05:50 -04:00
idk
afdc44afc6 Fix the helpers 2019-08-31 03:02:13 -04:00
idk
6b873f4fc2 update the interface 2019-08-31 02:50:11 -04:00
idk
c427d576cb more prep to reduce the amount of repeated configuration code 2019-08-31 00:13:20 -04:00
idk
383fafea25 more prep to reduce the amount of repeated configuration code 2019-08-31 00:13:10 -04:00
idk
9254afc776 move config stuff around 2019-08-25 20:32:50 -04:00
idk
29c48f906c begin config cleanup 2019-08-25 19:21:11 -04:00
idk
38a4e1b3ad begin config cleanup 2019-08-25 19:20:54 -04:00
57 changed files with 2336 additions and 3171 deletions

3
.gitignore vendored
View File

@ -4,3 +4,6 @@ bin/*
*.i2pkeys
*/*.i2pkeys
README.md.asc
samcatd
*/*.pem
*.pem

View File

@ -7,6 +7,7 @@ network = host
samhost = sam-host
samport = 7656
args = -r
USER_GH=eyedeekay
PREFIX := /
VAR := var/
@ -16,7 +17,7 @@ LOG := log/
ETC := etc/
USR := usr/
LOCAL := local/
VERSION := 0.1
VERSION := 0.32.09
GO111MODULE=on
@ -24,8 +25,12 @@ echo:
@echo "$(GOPATH)"
find . -path ./.go -prune -o -name "*.go" -exec gofmt -w {} \;
find . -path ./.go -prune -o -name "*.i2pkeys" -exec rm {} \;
find . -path ./.go -prune -o -name "*.pem" -exec rm {} \;
find . -path ./.go -prune -o -name "*.go" -exec cat {} \; | nl
tag:
gothub release -s $(GITHUB_TOKEN) -u $(USER_GH) -r $(packagename) -t v$(VERSION) -d "I2P Tunnel Management tool for Go applications"
recopy:
#find ./tcp/ -name '*.go' -exec cp -rv {} . \;
#sed -i '1s|^|//AUTO-GENERATED FOR BACKWARD COMPATIBILITY, USE ./tcp in the future\n|' *.go
@ -36,7 +41,7 @@ fix-debian:
find ./debian -type f -exec sed -i 's|eyedeekay@safe-mail.net|hankhill19580@gmail.com|g' {} \;
try:
cd etc/samcatd/ && ../../bin/samcatd -f tunnels.ini
./bin/samcatd -f etc/samcatd/tunnels.ini
test: test-keys test-ntcp test-ssu test-config test-manager
@ -84,6 +89,15 @@ daemon: clean-daemon bin/$(samcatd)
daemon-webview: bin/$(samcatd)-webview
daemon-cli: bin/$(samcatd)-cli
bin/$(samcatd)-cli:
mkdir -p bin
cd samcatd && go build -a -tags "netgo cli" \
-ldflags '-w -extldflags "-static"' \
-o ../bin/$(samcatd)-cli \
./*.go
bin/$(samcatd):
mkdir -p bin
cd samcatd && go build -a -tags "netgo static" \
@ -100,9 +114,9 @@ bin/$(samcatd)-webview:
update:
git config --global url."git@github.com:RTradeLtd".insteadOf "https://github.com/RTradeLtd"
all: daemon daemon-webview
all: daemon-cli daemon daemon-webview
clean: clean-all
clean: clean-all echo
clean-all: clean-daemon
@ -149,6 +163,7 @@ key-management:
example-config:
@echo "example config - valid for both ephsite and samcat" >> USAGE.md
@echo "==================================================" >> USAGE.md
@echo "" >> USAGE.md
@echo "Options are still being added, pretty much as fast as I can put them" >> USAGE.md
@echo "in. For up-to-the-minute options, see [the checklist](config/CHECKLIST.md)" >> USAGE.md
@echo "" >> USAGE.md
@ -222,3 +237,15 @@ tar:
--exclude .go \
--exclude bin \
-cJvf ../$(packagename)_$(VERSION).orig.tar.xz .
sed:
sed -i 's|func(\*Conf)|func(samtunnel.SAMTunnel)|g' ./config/*.go
sed -i 's|func(c \*Conf)|func(c samtunnel.SAMTunnel)|g' ./config/*.go
tasks:
golint ./tcp
#golint ./udp
#golint ./config
#golint ./config
#golint ./config
#golint ./config

View File

@ -58,12 +58,12 @@ key:
[*] - i2cp.tcp.port 1-65535 7654 Router I2CP port. If the client is running in the same JVM as a router, this option is ignored, and the client connects to that router internally.
Default Description
[C] - i2cp.accessList null Comma- or space-separated list of Base64 peer Hashes used for either access list or blacklist. As of release 0.7.13.
[U] - i2cp.destination.sigType DSA_SHA1 Use the access list as a whitelist for incoming connections. The name or number of the signature type for a transient destination. As of release 0.9.12.
[C] - i2cp.enableAccessList false Use the access list as a whitelist for incoming connections. As of release 0.7.13.
[C] - i2cp.enableBlackList false Use the access list as a blacklist for incoming connections. As of release 0.7.13.
[C] - i2cp.accessList null Comma- or space-separated list of Base64 peer Hashes used for either access list or blocklist. As of release 0.7.13.
[U] - i2cp.destination.sigType DSA_SHA1 Use the access list as a allowlist for incoming connections. The name or number of the signature type for a transient destination. As of release 0.9.12.
[C] - i2cp.enableAccessList false Use the access list as a allowlist for incoming connections. As of release 0.7.13.
[C] - i2cp.enableBlackList false Use the access list as a blocklist for incoming connections. As of release 0.7.13.
[U] - i2p.streaming.answerPings true Whether to respond to incoming pings
[U] - i2p.streaming.blacklist null Comma- or space-separated list of Base64 peer Hashes to be blacklisted for incoming connections to ALL destinations in the context. This option must be set in the context properties, NOT in the createManager() options argument. Note that setting this in the router context will not affect clients outside the router in a separate JVM and context. As of release 0.9.3.
[U] - i2p.streaming.blocklist null Comma- or space-separated list of Base64 peer Hashes to be blocklisted for incoming connections to ALL destinations in the context. This option must be set in the context properties, NOT in the createManager() options argument. Note that setting this in the router context will not affect clients outside the router in a separate JVM and context. As of release 0.9.3.
[U] - i2p.streaming.bufferSize 64K How much transmit data (in bytes) will be accepted that hasn't been written out yet.
[U] - i2p.streaming.congestionAvoidanceGrowthRateFactor 1 When we're in congestion avoidance, we grow the window size at the rate of 1/(windowSize*factor). In standard TCP, window sizes are in bytes, while in I2P, window sizes are in messages. A higher number means slower growth.
[U] - i2p.streaming.connectDelay -1 How long to wait after instantiating a new con before actually attempting to connect. If this is <= 0, connect immediately with no initial data. If greater than 0, wait until the output stream is flushed, the buffer fills, or that many milliseconds pass, and include any initial data with the SYN.

View File

@ -55,12 +55,12 @@ key:
[U] - i2cp.tcp.port 1-65535 7654 Router I2CP port. If the client is running in the same JVM as a router, this option is ignored, and the client connects to that router internally.
Default Description
[U] - i2cp.accessList null Comma- or space-separated list of Base64 peer Hashes used for either access list or blacklist. As of release 0.7.13.
[U] - i2cp.destination.sigType DSA_SHA1 Use the access list as a whitelist for incoming connections. The name or number of the signature type for a transient destination. As of release 0.9.12.
[U] - i2cp.enableAccessList false Use the access list as a whitelist for incoming connections. As of release 0.7.13.
[U] - i2cp.enableBlackList false Use the access list as a blacklist for incoming connections. As of release 0.7.13.
[U] - i2cp.accessList null Comma- or space-separated list of Base64 peer Hashes used for either access list or blocklist. As of release 0.7.13.
[U] - i2cp.destination.sigType DSA_SHA1 Use the access list as a allowlist for incoming connections. The name or number of the signature type for a transient destination. As of release 0.9.12.
[U] - i2cp.enableAccessList false Use the access list as a allowlist for incoming connections. As of release 0.7.13.
[U] - i2cp.enableBlackList false Use the access list as a blocklist for incoming connections. As of release 0.7.13.
[U] - i2p.streaming.answerPings true Whether to respond to incoming pings
[U] - i2p.streaming.blacklist null Comma- or space-separated list of Base64 peer Hashes to be blacklisted for incoming connections to ALL destinations in the context. This option must be set in the context properties, NOT in the createManager() options argument. Note that setting this in the router context will not affect clients outside the router in a separate JVM and context. As of release 0.9.3.
[U] - i2p.streaming.blocklist null Comma- or space-separated list of Base64 peer Hashes to be blocklisted for incoming connections to ALL destinations in the context. This option must be set in the context properties, NOT in the createManager() options argument. Note that setting this in the router context will not affect clients outside the router in a separate JVM and context. As of release 0.9.3.
[U] - i2p.streaming.bufferSize 64K How much transmit data (in bytes) will be accepted that hasn't been written out yet.
[U] - i2p.streaming.congestionAvoidanceGrowthRateFactor 1 When we're in congestion avoidance, we grow the window size at the rate of 1/(windowSize*factor). In standard TCP, window sizes are in bytes, while in I2P, window sizes are in messages. A higher number means slower growth.
[U] - i2p.streaming.connectDelay -1 How long to wait after instantiating a new con before actually attempting to connect. If this is <= 0, connect immediately with no initial data. If greater than 0, wait until the output stream is flushed, the buffer fills, or that many milliseconds pass, and include any initial data with the SYN.

View File

@ -1,6 +1,8 @@
package i2ptunconf
import "strings"
import (
"strings"
)
// GetAccessListType takes an argument and a default. If the argument differs from the
// default, the argument is always returned. If the argument and default are
@ -20,20 +22,20 @@ func (c *Conf) GetAccessListType(arg, def string, label ...string) string {
func (c *Conf) SetAccessListType(label ...string) {
if v, ok := c.GetBool("i2cp.enableBlackList", label...); ok {
if v {
c.AccessListType = "blacklist"
c.AccessListType = "blocklist"
}
}
if v, ok := c.GetBool("i2cp.enableAccessList", label...); ok {
if v {
c.AccessListType = "whitelist"
c.AccessListType = "allowlist"
}
}
if c.AccessListType != "whitelist" && c.AccessListType != "blacklist" {
if c.AccessListType != "allowlist" && c.AccessListType != "blocklist" {
c.AccessListType = "none"
}
}
// AddAccessListMember adds a member to either the blacklist or the whitelist
// AddAccessListMember adds a member to either the blocklist or the allowlist
func (c *Conf) AddAccessListMember(key string) {
for _, item := range c.AccessList {
if item == key {
@ -44,9 +46,9 @@ func (c *Conf) AddAccessListMember(key string) {
}
func (c *Conf) accesslisttype() string {
if c.AccessListType == "whitelist" {
if c.AccessListType == "allowlist" {
return "i2cp.enableAccessList=true"
} else if c.AccessListType == "blacklist" {
} else if c.AccessListType == "blocklist" {
return "i2cp.enableBlackList=true"
} else if c.AccessListType == "none" {
return ""

182
config/conf.go Normal file
View File

@ -0,0 +1,182 @@
package i2ptunconf
import (
"fmt"
"strings"
)
import (
sfi2pkeys "github.com/eyedeekay/sam-forwarder/i2pkeys"
"github.com/eyedeekay/sam3/i2pkeys"
)
var err error
func (f *Conf) ID() string {
return f.TunName
}
func (f *Conf) Keys() i2pkeys.I2PKeys {
return f.LoadedKeys
}
func (f *Conf) Cleanup() {
}
func (f *Conf) GetType() string {
return f.Type
}
/*func (f *Conf) targetForPort443() string {
if f.TargetForPort443 != "" {
return "targetForPort.4443=" + f.TargetHost + ":" + f.TargetForPort443
}
return ""
}*/
func (f *Conf) print() []string {
lsk, lspk, lspsk := f.leasesetsettings()
return []string{
//f.targetForPort443(),
"inbound.length=" + fmt.Sprintf("%d", f.InLength),
"outbound.length=" + fmt.Sprintf("%d", f.OutLength),
"inbound.lengthVariance=" + fmt.Sprintf("%d", f.InVariance),
"outbound.lengthVariance=" + fmt.Sprintf("%d", f.OutVariance),
"inbound.backupQuantity=" + fmt.Sprintf("%d", f.InBackupQuantity),
"outbound.backupQuantity=" + fmt.Sprintf("%d", f.OutBackupQuantity),
"inbound.quantity=" + fmt.Sprintf("%d", f.InQuantity),
"outbound.quantity=" + fmt.Sprintf("%d", f.OutQuantity),
"inbound.allowZeroHop=" + fmt.Sprintf("%v", f.InAllowZeroHop),
"outbound.allowZeroHop=" + fmt.Sprintf("%v", f.OutAllowZeroHop),
"i2cp.fastRecieve=" + fmt.Sprintf("%v", f.FastRecieve),
"i2cp.gzip=" + fmt.Sprintf("%v", f.UseCompression),
"i2cp.reduceOnIdle=" + fmt.Sprintf("%v", f.ReduceIdle),
"i2cp.reduceIdleTime=" + fmt.Sprintf("%v", f.ReduceIdleTime),
"i2cp.reduceQuantity=" + fmt.Sprintf("%d", f.ReduceIdleQuantity),
"i2cp.closeOnIdle=" + fmt.Sprintf("%v", f.CloseIdle),
"i2cp.closeIdleTime=" + fmt.Sprintf("%d", f.CloseIdleTime),
"i2cp.messageReliability=" + f.MessageReliability,
"i2cp.encryptLeaseSet=" + fmt.Sprintf("%v", f.EncryptLeaseSet),
"i2cp.leaseSetEncType=" + fmt.Sprintf("%s", f.LeaseSetEncType),
lsk, lspk, lspsk,
f.accesslisttype(),
f.accesslist(),
}
}
func (f *Conf) Props() map[string]string {
r := make(map[string]string)
print := f.print()
print = append(print, "base32="+f.Base32())
print = append(print, "base64="+f.Base64())
print = append(print, "base32words="+f.Base32Readable())
for _, prop := range print {
k, v := sfi2pkeys.Prop(prop)
r[k] = v
}
return r
}
func (f *Conf) Print() string {
var r string
r += "name=" + f.TunName + "\n"
r += "type=" + f.Type + "\n"
if f.Type == "http" {
r += "httpserver\n"
} else {
r += "ntcpserver\n"
}
for _, s := range f.print() {
r += s + "\n"
}
return strings.Replace(r, "\n\n", "\n", -1)
}
func (f *Conf) Search(search string) string {
terms := strings.Split(search, ",")
if search == "" {
return f.Print()
}
for _, value := range terms {
if !strings.Contains(f.Print(), value) {
return ""
}
}
return f.Print()
}
/*
func (f *Conf) accesslisttype() string {
if f.accessListType == "allowlist" {
return "i2cp.enableAccessList=true"
} else if f.accessListType == "blocklist" {
return "i2cp.enableBlackList=true"
} else if f.accessListType == "none" {
return ""
}
return ""
}
func (f *Conf) accesslist() string {
if f.accessListType != "" && len(f.accessList) > 0 {
r := ""
for _, s := range f.accessList {
r += s + ","
}
return "i2cp.accessList=" + strings.TrimSuffix(r, ",")
}
return ""
}
*/
func (f *Conf) 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
}
return r, s, t
}
// Target returns the host:port of the local service you want to forward to i2p
func (f *Conf) Target() string {
return f.TargetHost + ":" + f.TargetPort
}
func (f *Conf) sam() string {
return f.SamHost + ":" + f.SamPort
}
//Base32 returns the base32 address where the local service is being forwarded
func (f *Conf) Base32() string {
return f.LoadedKeys.Addr().Base32()
}
//Base32Readable will always be an empty string when used here.
func (f *Conf) Base32Readable() string {
return ""
}
//Base64 returns the base64 address where the local service is being forwarded
func (f *Conf) Base64() string {
return f.LoadedKeys.Addr().Base64()
}
//Serve starts the SAM connection and and forwards the local host:port to i2p
func (f *Conf) Serve() error {
return nil
}
func (f *Conf) Up() bool {
return false
}
//Close shuts the whole thing down.
func (f *Conf) Close() error {
return nil
}

20
config/config-options.go Normal file
View File

@ -0,0 +1,20 @@
package i2ptunconf
//Option is a Conf Option
type Option func(*Conf) error
//SetTargetForPort sets the port of the Conf's SAM bridge using a string
/*func SetTargetForPort443(s string) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
port, err := strconv.Atoi(s)
if err != nil {
return fmt.Errorf("Invalid Target Port %s; non-number ", s)
}
if port < 65536 && port > -1 {
c.TargetForPort443 = s
return nil
}
return fmt.Errorf("Invalid port")
}
}
*/

View File

@ -22,6 +22,6 @@ func (c *Conf) SetClientDest(label ...string) {
if v, ok := c.Get("destination", label...); ok {
c.ClientDest = v
} else {
c.ClientDest = v
c.ClientDest = ""
}
}

View File

@ -1,5 +1,7 @@
package i2ptunconf
//
// GetDir takes an argument and a default. If the argument differs from the
// default, the argument is always returned. If the argument and default are
// the same and the key exists, the key is returned. If the key is absent, the

1
config/helpers/helper.go Normal file
View File

@ -0,0 +1 @@
package i2ptunhelper

View File

@ -1,13 +1,15 @@
package i2ptunconf
package i2ptunhelper
import (
"github.com/eyedeekay/httptunnel"
"github.com/eyedeekay/httptunnel/multiproxy"
"github.com/eyedeekay/sam-forwarder/config"
"github.com/eyedeekay/sam-forwarder/options"
"github.com/eyedeekay/sam-forwarder/tcp"
"github.com/eyedeekay/sam-forwarder/udp"
)
func NewSAMHTTPClientFromConf(config *Conf) (*i2phttpproxy.SAMHTTPProxy, error) {
func NewSAMHTTPClientFromConf(config *i2ptunconf.Conf) (*i2phttpproxy.SAMHTTPProxy, error) {
if config != nil {
return i2phttpproxy.NewHttpProxy(
i2phttpproxy.SetName(config.TunName),
@ -40,7 +42,7 @@ func NewSAMHTTPClientFromConf(config *Conf) (*i2phttpproxy.SAMHTTPProxy, error)
// NewSAMClientForwarderFromConfig generates a new SAMForwarder from a config file
func NewSAMHTTPClientFromConfig(iniFile, SamHost, SamPort string, label ...string) (*i2phttpproxy.SAMHTTPProxy, error) {
if iniFile != "none" {
config, err := NewI2PTunConf(iniFile, label...)
config, err := i2ptunconf.NewI2PTunConf(iniFile, label...)
if err != nil {
return nil, err
}
@ -55,7 +57,7 @@ func NewSAMHTTPClientFromConfig(iniFile, SamHost, SamPort string, label ...strin
return nil, nil
}
func NewSAMBrowserClientFromConf(config *Conf) (*i2pbrowserproxy.SAMMultiProxy, error) {
func NewSAMBrowserClientFromConf(config *i2ptunconf.Conf) (*i2pbrowserproxy.SAMMultiProxy, error) {
if config != nil {
return i2pbrowserproxy.NewHttpProxy(
i2pbrowserproxy.SetName(config.TunName),
@ -87,7 +89,7 @@ func NewSAMBrowserClientFromConf(config *Conf) (*i2pbrowserproxy.SAMMultiProxy,
func NewSAMBrowserClientFromConfig(iniFile, SamHost, SamPort string, label ...string) (*i2pbrowserproxy.SAMMultiProxy, error) {
if iniFile != "none" {
config, err := NewI2PTunConf(iniFile, label...)
config, err := i2ptunconf.NewI2PTunConf(iniFile, label...)
if err != nil {
return nil, err
}
@ -103,43 +105,43 @@ func NewSAMBrowserClientFromConfig(iniFile, SamHost, SamPort string, label ...st
}
// NewSAMClientForwarderFromConf generates a SAMforwarder from *i2ptunconf.Conf
func NewSAMClientForwarderFromConf(config *Conf) (*samforwarder.SAMClientForwarder, error) {
func NewSAMClientForwarderFromConf(config *i2ptunconf.Conf) (*samforwarder.SAMClientForwarder, error) {
if config != nil {
return samforwarder.NewSAMClientForwarderFromOptions(
samforwarder.SetClientSaveFile(config.SaveFile),
samforwarder.SetClientFilePath(config.SaveDirectory),
samforwarder.SetClientHost(config.TargetHost),
samforwarder.SetClientPort(config.TargetPort),
samforwarder.SetClientSAMHost(config.SamHost),
samforwarder.SetClientSAMPort(config.SamPort),
samforwarder.SetClientSigType(config.SigType),
samforwarder.SetClientName(config.TunName),
samforwarder.SetClientInLength(config.InLength),
samforwarder.SetClientOutLength(config.OutLength),
samforwarder.SetClientInVariance(config.InVariance),
samforwarder.SetClientOutVariance(config.OutVariance),
samforwarder.SetClientInQuantity(config.InQuantity),
samforwarder.SetClientOutQuantity(config.OutQuantity),
samforwarder.SetClientInBackups(config.InBackupQuantity),
samforwarder.SetClientOutBackups(config.OutBackupQuantity),
samforwarder.SetClientEncrypt(config.EncryptLeaseSet),
samforwarder.SetClientLeaseSetKey(config.LeaseSetKey),
samforwarder.SetClientLeaseSetPrivateKey(config.LeaseSetPrivateKey),
samforwarder.SetClientLeaseSetPrivateSigningKey(config.LeaseSetPrivateSigningKey),
samforwarder.SetClientAllowZeroIn(config.InAllowZeroHop),
samforwarder.SetClientAllowZeroOut(config.OutAllowZeroHop),
samforwarder.SetClientFastRecieve(config.FastRecieve),
samforwarder.SetClientCompress(config.UseCompression),
samforwarder.SetClientReduceIdle(config.ReduceIdle),
samforwarder.SetClientReduceIdleTimeMs(config.ReduceIdleTime),
samforwarder.SetClientReduceIdleQuantity(config.ReduceIdleQuantity),
samforwarder.SetClientCloseIdle(config.CloseIdle),
samforwarder.SetClientCloseIdleTimeMs(config.CloseIdleTime),
samforwarder.SetClientAccessListType(config.AccessListType),
samforwarder.SetClientAccessList(config.AccessList),
samforwarder.SetClientMessageReliability(config.MessageReliability),
samforwarder.SetClientPassword(config.KeyFilePath),
samforwarder.SetClientDestination(config.ClientDest),
samoptions.SetSaveFile(config.SaveFile),
samoptions.SetFilePath(config.SaveDirectory),
samoptions.SetHost(config.TargetHost),
samoptions.SetPort(config.TargetPort),
samoptions.SetSAMHost(config.SamHost),
samoptions.SetSAMPort(config.SamPort),
samoptions.SetSigType(config.SigType),
samoptions.SetName(config.TunName),
samoptions.SetInLength(config.InLength),
samoptions.SetOutLength(config.OutLength),
samoptions.SetInVariance(config.InVariance),
samoptions.SetOutVariance(config.OutVariance),
samoptions.SetInQuantity(config.InQuantity),
samoptions.SetOutQuantity(config.OutQuantity),
samoptions.SetInBackups(config.InBackupQuantity),
samoptions.SetOutBackups(config.OutBackupQuantity),
samoptions.SetEncrypt(config.EncryptLeaseSet),
samoptions.SetLeaseSetKey(config.LeaseSetKey),
samoptions.SetLeaseSetPrivateKey(config.LeaseSetPrivateKey),
samoptions.SetLeaseSetPrivateSigningKey(config.LeaseSetPrivateSigningKey),
samoptions.SetAllowZeroIn(config.InAllowZeroHop),
samoptions.SetAllowZeroOut(config.OutAllowZeroHop),
samoptions.SetFastRecieve(config.FastRecieve),
samoptions.SetCompress(config.UseCompression),
samoptions.SetReduceIdle(config.ReduceIdle),
samoptions.SetReduceIdleTimeMs(config.ReduceIdleTime),
samoptions.SetReduceIdleQuantity(config.ReduceIdleQuantity),
samoptions.SetCloseIdle(config.CloseIdle),
samoptions.SetCloseIdleTimeMs(config.CloseIdleTime),
samoptions.SetAccessListType(config.AccessListType),
samoptions.SetAccessList(config.AccessList),
samoptions.SetMessageReliability(config.MessageReliability),
samoptions.SetPassword(config.KeyFilePath),
samoptions.SetDestination(config.ClientDest),
)
}
return nil, nil
@ -148,7 +150,7 @@ func NewSAMClientForwarderFromConf(config *Conf) (*samforwarder.SAMClientForward
// NewSAMClientForwarderFromConfig generates a new SAMForwarder from a config file
func NewSAMClientForwarderFromConfig(iniFile, SamHost, SamPort string, label ...string) (*samforwarder.SAMClientForwarder, error) {
if iniFile != "none" {
config, err := NewI2PTunConf(iniFile, label...)
config, err := i2ptunconf.NewI2PTunConf(iniFile, label...)
if err != nil {
return nil, err
}
@ -163,52 +165,52 @@ func NewSAMClientForwarderFromConfig(iniFile, SamHost, SamPort string, label ...
return nil, nil
}
// NewSAMSSUClientForwarderFromConf generates a SAMSSUforwarder from *i2ptunconf.Conf
func NewSAMSSUClientForwarderFromConf(config *Conf) (*samforwarderudp.SAMSSUClientForwarder, error) {
// NewSAMDGClientForwarderFromConf generates a SAMSSUforwarder from *i2ptunconf.Conf
func NewSAMDGClientForwarderFromConf(config *i2ptunconf.Conf) (*samforwarderudp.SAMDGClientForwarder, error) {
if config != nil {
return samforwarderudp.NewSAMSSUClientForwarderFromOptions(
samforwarderudp.SetClientSaveFile(config.SaveFile),
samforwarderudp.SetClientFilePath(config.SaveDirectory),
samforwarderudp.SetClientHost(config.TargetHost),
samforwarderudp.SetClientPort(config.TargetPort),
samforwarderudp.SetClientSAMHost(config.SamHost),
samforwarderudp.SetClientSAMPort(config.SamPort),
samforwarderudp.SetClientSigType(config.SigType),
samforwarderudp.SetClientName(config.TunName),
samforwarderudp.SetClientInLength(config.InLength),
samforwarderudp.SetClientOutLength(config.OutLength),
samforwarderudp.SetClientInVariance(config.InVariance),
samforwarderudp.SetClientOutVariance(config.OutVariance),
samforwarderudp.SetClientInQuantity(config.InQuantity),
samforwarderudp.SetClientOutQuantity(config.OutQuantity),
samforwarderudp.SetClientInBackups(config.InBackupQuantity),
samforwarderudp.SetClientOutBackups(config.OutBackupQuantity),
samforwarderudp.SetClientEncrypt(config.EncryptLeaseSet),
samforwarderudp.SetClientLeaseSetKey(config.LeaseSetKey),
samforwarderudp.SetClientLeaseSetPrivateKey(config.LeaseSetPrivateKey),
samforwarderudp.SetClientLeaseSetPrivateSigningKey(config.LeaseSetPrivateSigningKey),
samforwarderudp.SetClientAllowZeroIn(config.InAllowZeroHop),
samforwarderudp.SetClientAllowZeroOut(config.OutAllowZeroHop),
samforwarderudp.SetClientFastRecieve(config.FastRecieve),
samforwarderudp.SetClientCompress(config.UseCompression),
samforwarderudp.SetClientReduceIdle(config.ReduceIdle),
samforwarderudp.SetClientReduceIdleTimeMs(config.ReduceIdleTime),
samforwarderudp.SetClientReduceIdleQuantity(config.ReduceIdleQuantity),
samforwarderudp.SetClientCloseIdle(config.CloseIdle),
samforwarderudp.SetClientCloseIdleTimeMs(config.CloseIdleTime),
samforwarderudp.SetClientAccessListType(config.AccessListType),
samforwarderudp.SetClientAccessList(config.AccessList),
samforwarderudp.SetClientMessageReliability(config.MessageReliability),
samforwarderudp.SetClientPassword(config.KeyFilePath),
samforwarderudp.SetClientDestination(config.ClientDest),
return samforwarderudp.NewSAMDGClientForwarderFromOptions(
samoptions.SetSaveFile(config.SaveFile),
samoptions.SetFilePath(config.SaveDirectory),
samoptions.SetHost(config.TargetHost),
samoptions.SetPort(config.TargetPort),
samoptions.SetSAMHost(config.SamHost),
samoptions.SetSAMPort(config.SamPort),
samoptions.SetSigType(config.SigType),
samoptions.SetName(config.TunName),
samoptions.SetInLength(config.InLength),
samoptions.SetOutLength(config.OutLength),
samoptions.SetInVariance(config.InVariance),
samoptions.SetOutVariance(config.OutVariance),
samoptions.SetInQuantity(config.InQuantity),
samoptions.SetOutQuantity(config.OutQuantity),
samoptions.SetInBackups(config.InBackupQuantity),
samoptions.SetOutBackups(config.OutBackupQuantity),
samoptions.SetEncrypt(config.EncryptLeaseSet),
samoptions.SetLeaseSetKey(config.LeaseSetKey),
samoptions.SetLeaseSetPrivateKey(config.LeaseSetPrivateKey),
samoptions.SetLeaseSetPrivateSigningKey(config.LeaseSetPrivateSigningKey),
samoptions.SetAllowZeroIn(config.InAllowZeroHop),
samoptions.SetAllowZeroOut(config.OutAllowZeroHop),
samoptions.SetFastRecieve(config.FastRecieve),
samoptions.SetCompress(config.UseCompression),
samoptions.SetReduceIdle(config.ReduceIdle),
samoptions.SetReduceIdleTimeMs(config.ReduceIdleTime),
samoptions.SetReduceIdleQuantity(config.ReduceIdleQuantity),
samoptions.SetCloseIdle(config.CloseIdle),
samoptions.SetCloseIdleTimeMs(config.CloseIdleTime),
samoptions.SetAccessListType(config.AccessListType),
samoptions.SetAccessList(config.AccessList),
samoptions.SetMessageReliability(config.MessageReliability),
samoptions.SetPassword(config.KeyFilePath),
samoptions.SetDestination(config.ClientDest),
)
}
return nil, nil
}
func NewSAMSSUClientForwarderFromConfig(iniFile, SamHost, SamPort string, label ...string) (*samforwarderudp.SAMSSUClientForwarder, error) {
func NewSAMDGClientForwarderFromConfig(iniFile, SamHost, SamPort string, label ...string) (*samforwarderudp.SAMDGClientForwarder, error) {
if iniFile != "none" {
config, err := NewI2PTunConf(iniFile, label...)
config, err := i2ptunconf.NewI2PTunConf(iniFile, label...)
if err != nil {
return nil, err
}
@ -218,7 +220,7 @@ func NewSAMSSUClientForwarderFromConfig(iniFile, SamHost, SamPort string, label
if SamPort != "" && SamPort != "7656" {
config.SamPort = config.GetSAMPort(SamPort, config.SamPort)
}
return NewSAMSSUClientForwarderFromConf(config)
return NewSAMDGClientForwarderFromConf(config)
}
return nil, nil
}

View File

@ -0,0 +1,130 @@
package i2ptunhelper
import (
"github.com/eyedeekay/outproxy"
"github.com/eyedeekay/sam-forwarder/config"
)
// NewOutProxyFromConf generates a SAMforwarder from *i2ptunconf.Conf
func NewOutProxyFromConf(config *i2ptunconf.Conf) (*outproxy.OutProxy, error) {
if config != nil {
return outproxy.NewOutProxyFromOptions(
outproxy.SetType(config.Type),
outproxy.SetSaveFile(config.SaveFile),
outproxy.SetFilePath(config.SaveDirectory),
outproxy.SetHost(config.TargetHost),
outproxy.SetPort(config.TargetPort),
outproxy.SetSAMHost(config.SamHost),
outproxy.SetSAMPort(config.SamPort),
outproxy.SetSigType(config.SigType),
outproxy.SetName(config.TunName),
outproxy.SetInLength(config.InLength),
outproxy.SetOutLength(config.OutLength),
outproxy.SetInVariance(config.InVariance),
outproxy.SetOutVariance(config.OutVariance),
outproxy.SetInQuantity(config.InQuantity),
outproxy.SetOutQuantity(config.OutQuantity),
outproxy.SetInBackups(config.InBackupQuantity),
outproxy.SetOutBackups(config.OutBackupQuantity),
outproxy.SetEncrypt(config.EncryptLeaseSet),
outproxy.SetLeaseSetKey(config.LeaseSetKey),
outproxy.SetLeaseSetPrivateKey(config.LeaseSetPrivateKey),
outproxy.SetLeaseSetPrivateSigningKey(config.LeaseSetPrivateSigningKey),
outproxy.SetAllowZeroIn(config.InAllowZeroHop),
outproxy.SetAllowZeroOut(config.OutAllowZeroHop),
outproxy.SetFastRecieve(config.FastRecieve),
outproxy.SetCompress(config.UseCompression),
outproxy.SetReduceIdle(config.ReduceIdle),
outproxy.SetReduceIdleTimeMs(config.ReduceIdleTime),
outproxy.SetReduceIdleQuantity(config.ReduceIdleQuantity),
outproxy.SetCloseIdle(config.CloseIdle),
outproxy.SetCloseIdleTimeMs(config.CloseIdleTime),
outproxy.SetAccessListType(config.AccessListType),
outproxy.SetAccessList(config.AccessList),
outproxy.SetMessageReliability(config.MessageReliability),
outproxy.SetKeyFile(config.KeyFilePath),
//outproxy.SetTargetForPort443(config.TargetForPort443),
)
}
return nil, nil
}
// NewOutProxyFromConfig generates a new OutProxy from a config file
func NewOutProxyFromConfig(iniFile, SamHost, SamPort string, label ...string) (*outproxy.HttpOutProxy, error) {
if iniFile != "none" {
config, err := i2ptunconf.NewI2PTunConf(iniFile, label...)
if err != nil {
return nil, err
}
if SamHost != "" && SamHost != "127.0.0.1" && SamHost != "localhost" {
config.SamHost = config.GetSAMHost(SamHost, config.SamHost)
}
if SamPort != "" && SamPort != "7656" {
config.SamPort = config.GetSAMPort(SamPort, config.SamPort)
}
return NewHttpOutProxyFromConf(config)
}
return nil, nil
}
// NewOutProxyFromConf generates a SAMforwarder from *i2ptunconf.Conf
func NewHttpOutProxyFromConf(config *i2ptunconf.Conf) (*outproxy.HttpOutProxy, error) {
if config != nil {
return outproxy.NewHttpOutProxydFromOptions(
outproxy.SetHttpType(config.Type),
outproxy.SetHttpSaveFile(config.SaveFile),
outproxy.SetHttpFilePath(config.SaveDirectory),
outproxy.SetHttpHost(config.TargetHost),
outproxy.SetHttpPort(config.TargetPort),
outproxy.SetHttpSAMHost(config.SamHost),
outproxy.SetHttpSAMPort(config.SamPort),
outproxy.SetHttpSigType(config.SigType),
outproxy.SetHttpName(config.TunName),
outproxy.SetHttpInLength(config.InLength),
outproxy.SetHttpOutLength(config.OutLength),
outproxy.SetHttpInVariance(config.InVariance),
outproxy.SetHttpOutVariance(config.OutVariance),
outproxy.SetHttpInQuantity(config.InQuantity),
outproxy.SetHttpOutQuantity(config.OutQuantity),
outproxy.SetHttpInBackups(config.InBackupQuantity),
outproxy.SetHttpOutBackups(config.OutBackupQuantity),
outproxy.SetHttpEncrypt(config.EncryptLeaseSet),
outproxy.SetHttpLeaseSetKey(config.LeaseSetKey),
outproxy.SetHttpLeaseSetPrivateKey(config.LeaseSetPrivateKey),
outproxy.SetHttpLeaseSetPrivateSigningKey(config.LeaseSetPrivateSigningKey),
outproxy.SetHttpAllowZeroIn(config.InAllowZeroHop),
outproxy.SetHttpAllowZeroOut(config.OutAllowZeroHop),
outproxy.SetHttpFastRecieve(config.FastRecieve),
outproxy.SetHttpCompress(config.UseCompression),
outproxy.SetHttpReduceIdle(config.ReduceIdle),
outproxy.SetHttpReduceIdleTimeMs(config.ReduceIdleTime),
outproxy.SetHttpReduceIdleQuantity(config.ReduceIdleQuantity),
outproxy.SetHttpCloseIdle(config.CloseIdle),
outproxy.SetHttpCloseIdleTimeMs(config.CloseIdleTime),
outproxy.SetHttpAccessListType(config.AccessListType),
outproxy.SetHttpAccessList(config.AccessList),
outproxy.SetHttpMessageReliability(config.MessageReliability),
outproxy.SetHttpKeyFile(config.KeyFilePath),
//outproxy.SetHttpTargetForPort443(config.TargetForPort443),
)
}
return nil, nil
}
// NewOutProxyFromConfig generates a new OutProxy from a config file
func NewHttpOutProxyFromConfig(iniFile, SamHost, SamPort string, label ...string) (*outproxy.OutProxy, error) {
if iniFile != "none" {
config, err := i2ptunconf.NewI2PTunConf(iniFile, label...)
if err != nil {
return nil, err
}
if SamHost != "" && SamHost != "127.0.0.1" && SamHost != "localhost" {
config.SamHost = config.GetSAMHost(SamHost, config.SamHost)
}
if SamPort != "" && SamPort != "7656" {
config.SamPort = config.GetSAMPort(SamPort, config.SamPort)
}
return NewOutProxyFromConf(config)
}
return nil, nil
}

View File

@ -0,0 +1,194 @@
package i2ptunhelper
import (
"github.com/eyedeekay/eephttpd"
"github.com/eyedeekay/sam-forwarder/config"
"github.com/eyedeekay/sam-forwarder/options"
"github.com/eyedeekay/sam-forwarder/tcp"
"github.com/eyedeekay/sam-forwarder/udp"
)
// NewSAMForwarderFromConf generates a SAMforwarder from *i2ptunconf.Conf
func NewSAMForwarderFromConf(config *i2ptunconf.Conf) (*samforwarder.SAMForwarder, error) {
if config != nil {
return samforwarder.NewSAMForwarderFromOptions(
samoptions.SetType(config.Type),
samoptions.SetSaveFile(config.SaveFile),
samoptions.SetFilePath(config.SaveDirectory),
samoptions.SetHost(config.TargetHost),
samoptions.SetPort(config.TargetPort),
samoptions.SetSAMHost(config.SamHost),
samoptions.SetSAMPort(config.SamPort),
samoptions.SetSigType(config.SigType),
samoptions.SetName(config.TunName),
samoptions.SetInLength(config.InLength),
samoptions.SetOutLength(config.OutLength),
samoptions.SetInVariance(config.InVariance),
samoptions.SetOutVariance(config.OutVariance),
samoptions.SetInQuantity(config.InQuantity),
samoptions.SetOutQuantity(config.OutQuantity),
samoptions.SetInBackups(config.InBackupQuantity),
samoptions.SetOutBackups(config.OutBackupQuantity),
samoptions.SetEncrypt(config.EncryptLeaseSet),
samoptions.SetLeaseSetKey(config.LeaseSetKey),
samoptions.SetLeaseSetPrivateKey(config.LeaseSetPrivateKey),
samoptions.SetLeaseSetPrivateSigningKey(config.LeaseSetPrivateSigningKey),
samoptions.SetAllowZeroIn(config.InAllowZeroHop),
samoptions.SetAllowZeroOut(config.OutAllowZeroHop),
samoptions.SetFastRecieve(config.FastRecieve),
samoptions.SetCompress(config.UseCompression),
samoptions.SetReduceIdle(config.ReduceIdle),
samoptions.SetReduceIdleTimeMs(config.ReduceIdleTime),
samoptions.SetReduceIdleQuantity(config.ReduceIdleQuantity),
samoptions.SetCloseIdle(config.CloseIdle),
samoptions.SetCloseIdleTimeMs(config.CloseIdleTime),
samoptions.SetAccessListType(config.AccessListType),
samoptions.SetAccessList(config.AccessList),
samoptions.SetMessageReliability(config.MessageReliability),
samoptions.SetKeyFile(config.KeyFilePath),
//samoptions.SetTargetForPort443(config.TargetForPort443),
)
}
return nil, nil
}
// NewSAMForwarderFromConfig generates a new SAMForwarder from a config file
func NewSAMForwarderFromConfig(iniFile, SamHost, SamPort string, label ...string) (*samforwarder.SAMForwarder, error) {
if iniFile != "none" {
config, err := i2ptunconf.NewI2PTunConf(iniFile, label...)
if err != nil {
return nil, err
}
if SamHost != "" && SamHost != "127.0.0.1" && SamHost != "localhost" {
config.SamHost = config.GetSAMHost(SamHost, config.SamHost)
}
if SamPort != "" && SamPort != "7656" {
config.SamPort = config.GetSAMPort(SamPort, config.SamPort)
}
return NewSAMForwarderFromConf(config)
}
return nil, nil
}
// NewSAMDGForwarderFromConf generates a SAMSSUforwarder from *i2ptunconf.Conf
func NewSAMDGForwarderFromConf(config *i2ptunconf.Conf) (*samforwarderudp.SAMDGForwarder, error) {
if config != nil {
return samforwarderudp.NewSAMDGForwarderFromOptions(
samoptions.SetSaveFile(config.SaveFile),
samoptions.SetFilePath(config.SaveDirectory),
samoptions.SetHost(config.TargetHost),
samoptions.SetPort(config.TargetPort),
samoptions.SetSAMHost(config.SamHost),
samoptions.SetSAMPort(config.SamPort),
samoptions.SetSigType(config.SigType),
samoptions.SetName(config.TunName),
samoptions.SetInLength(config.InLength),
samoptions.SetOutLength(config.OutLength),
samoptions.SetInVariance(config.InVariance),
samoptions.SetOutVariance(config.OutVariance),
samoptions.SetInQuantity(config.InQuantity),
samoptions.SetOutQuantity(config.OutQuantity),
samoptions.SetInBackups(config.InBackupQuantity),
samoptions.SetOutBackups(config.OutBackupQuantity),
samoptions.SetEncrypt(config.EncryptLeaseSet),
samoptions.SetLeaseSetKey(config.LeaseSetKey),
samoptions.SetLeaseSetPrivateKey(config.LeaseSetPrivateKey),
samoptions.SetLeaseSetPrivateSigningKey(config.LeaseSetPrivateSigningKey),
samoptions.SetAllowZeroIn(config.InAllowZeroHop),
samoptions.SetAllowZeroOut(config.OutAllowZeroHop),
samoptions.SetFastRecieve(config.FastRecieve),
samoptions.SetCompress(config.UseCompression),
samoptions.SetReduceIdle(config.ReduceIdle),
samoptions.SetReduceIdleTimeMs(config.ReduceIdleTime),
samoptions.SetReduceIdleQuantity(config.ReduceIdleQuantity),
samoptions.SetCloseIdle(config.CloseIdle),
samoptions.SetCloseIdleTimeMs(config.CloseIdleTime),
samoptions.SetAccessListType(config.AccessListType),
samoptions.SetAccessList(config.AccessList),
samoptions.SetMessageReliability(config.MessageReliability),
samoptions.SetKeyFile(config.KeyFilePath),
)
}
return nil, nil
}
// NewSAMDGForwarderFromConfig generates a new SAMDGForwarder from a config file
func NewSAMDGForwarderFromConfig(iniFile, SamHost, SamPort string, label ...string) (*samforwarderudp.SAMDGForwarder, error) {
if iniFile != "none" {
config, err := i2ptunconf.NewI2PTunConf(iniFile, label...)
if err != nil {
return nil, err
}
if SamHost != "" && SamHost != "127.0.0.1" && SamHost != "localhost" {
config.SamHost = config.GetSAMHost(SamHost, config.SamHost)
}
if SamPort != "" && SamPort != "7656" {
config.SamPort = config.GetSAMPort(SamPort, config.SamPort)
}
return NewSAMDGForwarderFromConf(config)
}
return nil, nil
}
// NewEepHttpdFromConf generates a SAMforwarder from *i2ptunconf.Conf
func NewEepHttpdFromConf(config *i2ptunconf.Conf) (*eephttpd.EepHttpd, error) {
if config != nil {
return eephttpd.NewEepHttpdFromOptions(
eephttpd.SetType(config.Type),
eephttpd.SetSaveFile(config.SaveFile),
eephttpd.SetFilePath(config.SaveDirectory),
eephttpd.SetHost(config.TargetHost),
eephttpd.SetPort(config.TargetPort),
eephttpd.SetSAMHost(config.SamHost),
eephttpd.SetSAMPort(config.SamPort),
eephttpd.SetSigType(config.SigType),
eephttpd.SetName(config.TunName),
eephttpd.SetInLength(config.InLength),
eephttpd.SetOutLength(config.OutLength),
eephttpd.SetInVariance(config.InVariance),
eephttpd.SetOutVariance(config.OutVariance),
eephttpd.SetInQuantity(config.InQuantity),
eephttpd.SetOutQuantity(config.OutQuantity),
eephttpd.SetInBackups(config.InBackupQuantity),
eephttpd.SetOutBackups(config.OutBackupQuantity),
eephttpd.SetEncrypt(config.EncryptLeaseSet),
eephttpd.SetLeaseSetKey(config.LeaseSetKey),
eephttpd.SetLeaseSetPrivateKey(config.LeaseSetPrivateKey),
eephttpd.SetLeaseSetPrivateSigningKey(config.LeaseSetPrivateSigningKey),
eephttpd.SetAllowZeroIn(config.InAllowZeroHop),
eephttpd.SetAllowZeroOut(config.OutAllowZeroHop),
eephttpd.SetFastRecieve(config.FastRecieve),
eephttpd.SetCompress(config.UseCompression),
eephttpd.SetReduceIdle(config.ReduceIdle),
eephttpd.SetReduceIdleTimeMs(config.ReduceIdleTime),
eephttpd.SetReduceIdleQuantity(config.ReduceIdleQuantity),
eephttpd.SetCloseIdle(config.CloseIdle),
eephttpd.SetCloseIdleTimeMs(config.CloseIdleTime),
eephttpd.SetAccessListType(config.AccessListType),
eephttpd.SetAccessList(config.AccessList),
eephttpd.SetMessageReliability(config.MessageReliability),
eephttpd.SetKeyFile(config.KeyFilePath),
eephttpd.SetServeDir(config.ServeDirectory),
//eephttpd.SetTargetForPort443(config.TargetForPort443),
)
}
return nil, nil
}
// NewEepHttpdFromConfig generates a new EepHttpd from a config file
func NewEepHttpdFromConfig(iniFile, SamHost, SamPort string, label ...string) (*eephttpd.EepHttpd, error) {
if iniFile != "none" {
config, err := i2ptunconf.NewI2PTunConf(iniFile, label...)
if err != nil {
return nil, err
}
if SamHost != "" && SamHost != "127.0.0.1" && SamHost != "localhost" {
config.SamHost = config.GetSAMHost(SamHost, config.SamHost)
}
if SamPort != "" && SamPort != "7656" {
config.SamPort = config.GetSAMPort(SamPort, config.SamPort)
}
return NewEepHttpdFromConf(config)
}
return nil, nil
}

View File

@ -103,3 +103,29 @@ func (c *Conf) SetLeasesetPrivateSigningKey(label ...string) {
c.LeaseSetPrivateSigningKey = ""
}
}
// GetLeaseSetEncType takes an argument and a default. If the argument differs from the
// default, the argument is always returned. If the argument and default are
// the same and the key exists, the key is returned. If the key is absent, the
// default is returned.
func (c *Conf) GetLeaseSetEncType(arg, def string, label ...string) string {
if arg != def {
return arg
}
if c.Config == nil {
return arg
}
if x, o := c.Get("i2cp.leaseSetEncType", label...); o {
return x
}
return arg
}
// SetLeaseSetEncType tells the conf to use encrypted leasesets the from the config file
func (c *Conf) SetLeaseSetEncType(label ...string) {
if v, ok := c.Get("i2cp.leaseSetEncType", label...); ok {
c.LeaseSetEncType = v
} else {
c.LeaseSetEncType = ""
}
}

View File

@ -47,6 +47,6 @@ func (c *Conf) SetTunName(label ...string) {
if v, ok := c.Get("keys", label...); ok {
c.TunName = v
} else {
c.TunName = "fowarder"
c.TunName = "forwarder"
}
}

View File

@ -1,5 +1,12 @@
package i2ptunconf
import (
"crypto/tls"
"strings"
"github.com/eyedeekay/sam-forwarder/tls"
)
// GetPort443 takes an argument and a default. If the argument differs from the
// default, the argument is always returned. If the argument and default are
// the same and the key exists, the key is returned. If the key is absent, the
@ -25,3 +32,80 @@ func (c *Conf) SetTargetPort443(label ...string) {
c.TargetForPort443 = ""
}
}
// Get
func (c *Conf) GetUseTLS(arg, def bool, label ...string) bool {
if arg != def {
return arg
}
if c.Config == nil {
return arg
}
if x, o := c.GetBool("usetls", label...); o {
return x
}
return arg
}
// SetAllowZeroHopOut sets the config to allow zero-hop tunnels
func (c *Conf) SetUseTLS(label ...string) {
if v, ok := c.GetBool("usetls", label...); ok {
c.UseTLS = v
} else {
c.UseTLS = false
}
}
// GetTLSConfig
func (c *Conf) GetTLSConfigCertPem(arg, def string, label ...string) string {
if arg != def {
return arg
}
if c.Config == nil {
return arg
}
if x, o := c.Get("cert.pem", label...); o {
return x
}
return arg
}
// SetClientDest sets the key name from the config file
func (c *Conf) SetTLSConfigCertPem(label ...string) {
if v, ok := c.Get("cert.pem", label...); ok {
c.Cert = v
} else {
c.Cert = ""
}
}
// GetTLSConfig
func (c *Conf) GetTLSConfigKeyPem(arg, def string, label ...string) string {
if arg != def {
return arg
}
if c.Config == nil {
return arg
}
if x, o := c.Get("key.pem", label...); o {
return x
}
return arg
}
// SetClientDest sets the key name from the config file
func (c *Conf) SetTLSConfigKeyPem(label ...string) {
if v, ok := c.Get("key.pem", label...); ok {
c.Pem = v
} else {
c.Pem = ""
}
}
func (c *Conf) TLSConfig() (*tls.Config, error) {
names := []string{c.Base32()}
if c.HostName != "" && strings.HasSuffix(c.HostName, ".i2p") {
names = append(names, c.HostName)
}
return i2ptls.TLSConfig(c.Cert, c.Pem, names)
}

View File

@ -1,6 +1,7 @@
package i2ptunconf
import (
// "crypto/tls"
"io/ioutil"
"log"
"os"
@ -10,62 +11,72 @@ import (
)
import (
// "github.com/eyedeekay/sam3"
"github.com/eyedeekay/sam3/i2pkeys"
"github.com/zieckey/goini"
)
// Conf is a tructure containing an ini config, with some functions to help
// when you use it for in conjunction with command-line flags
type Conf struct {
Config *goini.INI
FilePath string
KeyFilePath string
Labels []string
Client bool
ClientDest string
SigType string
Type string
SaveDirectory string
SaveFile bool
TargetHost string
TargetPort string
SamHost string
SamPort string
TunnelHost string
ControlHost string
ControlPort string
TargetForPort443 string
TunName string
EncryptLeaseSet bool
LeaseSetKey string
LeaseSetPrivateKey string
LeaseSetPrivateSigningKey string
InAllowZeroHop bool
OutAllowZeroHop bool
InLength int
OutLength int
InQuantity int
OutQuantity int
InVariance int
OutVariance int
InBackupQuantity int
OutBackupQuantity int
UseCompression bool
FastRecieve bool
ReduceIdle bool
ReduceIdleTime int
ReduceIdleQuantity int
CloseIdle bool
CloseIdleTime int
AccessListType string
AccessList []string
MessageReliability string
exists bool
UserName string
Password string
Config *goini.INI `default:&goini.INI{}`
FilePath string `default:"./"`
KeyFilePath string `default:"./"`
Labels []string `default:{""}`
Client bool `default:true`
ClientDest string `default:"idk.i2p"`
SigType string `default:"SIGNATURE_TYPE=EdDSA_SHA512_Ed25519"`
Type string `default:"client"`
SaveDirectory string `default:"./"`
ServeDirectory string `default:"./www"`
SaveFile bool `default:false`
TargetHost string `default:"127.0.0.1"`
TargetPort string `default:"7778"`
SamHost string `default:"127.0.0.1"`
SamPort string `default:"7656"`
TunnelHost string `default:"127.0.0.1"`
ControlHost string `default:"127.0.0.1"`
ControlPort string `default:"7951"`
TargetForPort443 string `default:""`
TunName string `default:"goi2ptunnel"`
EncryptLeaseSet bool `default:false`
LeaseSetKey string `default:""`
LeaseSetEncType string `default:"4,0"`
LeaseSetPrivateKey string `default:""`
LeaseSetPrivateSigningKey string `default:""`
InAllowZeroHop bool `default:false`
OutAllowZeroHop bool `default:false`
InLength int `default:3`
OutLength int `default:3`
InQuantity int `default:1`
OutQuantity int `default:1`
InVariance int `default:0`
OutVariance int `default:0`
InBackupQuantity int `default:1`
OutBackupQuantity int `default:1`
UseCompression bool `default:true`
FastRecieve bool `default:true`
ReduceIdle bool `default:false`
ReduceIdleTime int `default:36000000`
ReduceIdleQuantity int `default:1`
CloseIdle bool `default:false`
CloseIdleTime int `default:36000000`
AccessListType string `default:"none"`
AccessList []string `default:{""}`
MessageReliability string `default:""`
exists bool `default:false`
UserName string `default:""`
Password string `default:""`
UseTLS bool `default:false`
Cert string `default:""`
Pem string `default:""`
HostName string `default:""`
//TLSConf *tls.Config
LoadedKeys i2pkeys.I2PKeys
}
// Print returns and prints a formatted list of configured tunnel settings.
func (c *Conf) Print() []string {
// PrintSlice returns and prints a formatted list of configured tunnel settings.
func (c *Conf) PrintSlice() []string {
confstring := []string{
c.SignatureType(),
"inbound.length=" + strconv.Itoa(c.InLength),
@ -94,7 +105,7 @@ func (c *Conf) Print() []string {
c.lsspk(),
}
log.Println(confstring)
log.Println("Tunnel:", c.TunName, "using config:", confstring)
return confstring
}
@ -242,6 +253,7 @@ func (c *Conf) I2PINILoad(iniFile string, label ...string) error {
c.SetTunName(label...)
c.SetSigType(label...)
c.SetEncryptLease(label...)
c.SetLeaseSetEncType(label...)
c.SetLeasesetKey(label...)
c.SetLeasesetPrivateKey(label...)
c.SetLeasesetPrivateSigningKey(label...)
@ -271,6 +283,10 @@ func (c *Conf) I2PINILoad(iniFile string, label ...string) error {
c.SetPassword(label...)
c.SetControlHost(label...)
c.SetControlPort(label...)
c.SetWWWDir(label...)
c.SetUseTLS(label...)
c.SetTLSConfigCertPem(label...)
c.SetTLSConfigKeyPem(label...)
if v, ok := c.Get("i2cp.accessList", label...); ok {
csv := strings.Split(v, ",")
for _, z := range csv {
@ -283,11 +299,19 @@ func (c *Conf) I2PINILoad(iniFile string, label ...string) error {
// NewI2PBlankTunConf returns an empty but intialized tunconf
func NewI2PBlankTunConf() *Conf {
var c Conf
// var c Conf
c := new(Conf)
c.SamHost = "127.0.0.1"
c.SamPort = "7656"
c.TunName = "unksam"
c.TargetHost = "127.0.0.1"
c.TargetPort = "0"
c.ClientDest = "idk.i2p"
c.LeaseSetEncType = "4,0"
c.Config = &goini.INI{}
c.Config = goini.New()
c.Config.Parse([]byte(""), "\n", "=")
return &c
c.Config.Parse([]byte("[client]\nsamhost=\"127.0.0.1\"\nsamport=\"7656\"\n"), "\n", "=")
return c
}
// NewI2PTunConf returns a Conf structure from an ini file, for modification

View File

@ -1,128 +0,0 @@
package i2ptunconf
import (
"github.com/eyedeekay/sam-forwarder/tcp"
"github.com/eyedeekay/sam-forwarder/udp"
)
// NewSAMForwarderFromConf generates a SAMforwarder from *i2ptunconf.Conf
func NewSAMForwarderFromConf(config *Conf) (*samforwarder.SAMForwarder, error) {
if config != nil {
return samforwarder.NewSAMForwarderFromOptions(
samforwarder.SetType(config.Type),
samforwarder.SetSaveFile(config.SaveFile),
samforwarder.SetFilePath(config.SaveDirectory),
samforwarder.SetHost(config.TargetHost),
samforwarder.SetPort(config.TargetPort),
samforwarder.SetSAMHost(config.SamHost),
samforwarder.SetSAMPort(config.SamPort),
samforwarder.SetSigType(config.SigType),
samforwarder.SetName(config.TunName),
samforwarder.SetInLength(config.InLength),
samforwarder.SetOutLength(config.OutLength),
samforwarder.SetInVariance(config.InVariance),
samforwarder.SetOutVariance(config.OutVariance),
samforwarder.SetInQuantity(config.InQuantity),
samforwarder.SetOutQuantity(config.OutQuantity),
samforwarder.SetInBackups(config.InBackupQuantity),
samforwarder.SetOutBackups(config.OutBackupQuantity),
samforwarder.SetEncrypt(config.EncryptLeaseSet),
samforwarder.SetLeaseSetKey(config.LeaseSetKey),
samforwarder.SetLeaseSetPrivateKey(config.LeaseSetPrivateKey),
samforwarder.SetLeaseSetPrivateSigningKey(config.LeaseSetPrivateSigningKey),
samforwarder.SetAllowZeroIn(config.InAllowZeroHop),
samforwarder.SetAllowZeroOut(config.OutAllowZeroHop),
samforwarder.SetFastRecieve(config.FastRecieve),
samforwarder.SetCompress(config.UseCompression),
samforwarder.SetReduceIdle(config.ReduceIdle),
samforwarder.SetReduceIdleTimeMs(config.ReduceIdleTime),
samforwarder.SetReduceIdleQuantity(config.ReduceIdleQuantity),
samforwarder.SetCloseIdle(config.CloseIdle),
samforwarder.SetCloseIdleTimeMs(config.CloseIdleTime),
samforwarder.SetAccessListType(config.AccessListType),
samforwarder.SetAccessList(config.AccessList),
samforwarder.SetMessageReliability(config.MessageReliability),
samforwarder.SetKeyFile(config.KeyFilePath),
//samforwarder.SetTargetForPort443(config.TargetForPort443),
)
}
return nil, nil
}
// NewSAMForwarderFromConfig generates a new SAMForwarder from a config file
func NewSAMForwarderFromConfig(iniFile, SamHost, SamPort string, label ...string) (*samforwarder.SAMForwarder, error) {
if iniFile != "none" {
config, err := NewI2PTunConf(iniFile, label...)
if err != nil {
return nil, err
}
if SamHost != "" && SamHost != "127.0.0.1" && SamHost != "localhost" {
config.SamHost = config.GetSAMHost(SamHost, config.SamHost)
}
if SamPort != "" && SamPort != "7656" {
config.SamPort = config.GetSAMPort(SamPort, config.SamPort)
}
return NewSAMForwarderFromConf(config)
}
return nil, nil
}
// NewSAMSSUForwarderFromConf generates a SAMSSUforwarder from *i2ptunconf.Conf
func NewSAMSSUForwarderFromConf(config *Conf) (*samforwarderudp.SAMSSUForwarder, error) {
if config != nil {
return samforwarderudp.NewSAMSSUForwarderFromOptions(
samforwarderudp.SetSaveFile(config.SaveFile),
samforwarderudp.SetFilePath(config.SaveDirectory),
samforwarderudp.SetHost(config.TargetHost),
samforwarderudp.SetPort(config.TargetPort),
samforwarderudp.SetSAMHost(config.SamHost),
samforwarderudp.SetSAMPort(config.SamPort),
samforwarderudp.SetSigType(config.SigType),
samforwarderudp.SetName(config.TunName),
samforwarderudp.SetInLength(config.InLength),
samforwarderudp.SetOutLength(config.OutLength),
samforwarderudp.SetInVariance(config.InVariance),
samforwarderudp.SetOutVariance(config.OutVariance),
samforwarderudp.SetInQuantity(config.InQuantity),
samforwarderudp.SetOutQuantity(config.OutQuantity),
samforwarderudp.SetInBackups(config.InBackupQuantity),
samforwarderudp.SetOutBackups(config.OutBackupQuantity),
samforwarderudp.SetEncrypt(config.EncryptLeaseSet),
samforwarderudp.SetLeaseSetKey(config.LeaseSetKey),
samforwarderudp.SetLeaseSetPrivateKey(config.LeaseSetPrivateKey),
samforwarderudp.SetLeaseSetPrivateSigningKey(config.LeaseSetPrivateSigningKey),
samforwarderudp.SetAllowZeroIn(config.InAllowZeroHop),
samforwarderudp.SetAllowZeroOut(config.OutAllowZeroHop),
samforwarderudp.SetFastRecieve(config.FastRecieve),
samforwarderudp.SetCompress(config.UseCompression),
samforwarderudp.SetReduceIdle(config.ReduceIdle),
samforwarderudp.SetReduceIdleTimeMs(config.ReduceIdleTime),
samforwarderudp.SetReduceIdleQuantity(config.ReduceIdleQuantity),
samforwarderudp.SetCloseIdle(config.CloseIdle),
samforwarderudp.SetCloseIdleTimeMs(config.CloseIdleTime),
samforwarderudp.SetAccessListType(config.AccessListType),
samforwarderudp.SetAccessList(config.AccessList),
samforwarderudp.SetMessageReliability(config.MessageReliability),
samforwarderudp.SetKeyFile(config.KeyFilePath),
)
}
return nil, nil
}
// NewSAMSSUForwarderFromConfig generates a new SAMSSUForwarder from a config file
func NewSAMSSUForwarderFromConfig(iniFile, SamHost, SamPort string, label ...string) (*samforwarderudp.SAMSSUForwarder, error) {
if iniFile != "none" {
config, err := NewI2PTunConf(iniFile, label...)
if err != nil {
return nil, err
}
if SamHost != "" && SamHost != "127.0.0.1" && SamHost != "localhost" {
config.SamHost = config.GetSAMHost(SamHost, config.SamHost)
}
if SamPort != "" && SamPort != "7656" {
config.SamPort = config.GetSAMPort(SamPort, config.SamPort)
}
return NewSAMSSUForwarderFromConf(config)
}
return nil, nil
}

View File

@ -8,7 +8,7 @@ import (
// default, the argument is always returned. If the argument and default are
// the same and the key exists, the key is returned. If the key is absent, the
// default is returned.
func (c *Conf) GetType(argc, argu, argh bool, def string, label ...string) string {
func (c *Conf) GetTypes(argc, argu, argh bool, def string, label ...string) string {
var typ string
if argu {
typ += "udp"
@ -25,15 +25,33 @@ func (c *Conf) GetType(argc, argu, argh bool, def string, label ...string) strin
} else {
typ += "server"
}
if typ != def {
return typ
}
}
if def == "kcpclient" {
typ = "kcpclient"
return def
}
if def == "kcpserver" {
typ = "kcpserver"
return def
}
if typ != def {
return typ
if def == "eephttpd" {
return def
}
if def == "vpnclient" {
return def
}
if def == "vpnserver" {
return def
}
if def == "outproxy" {
return def
}
if def == "outproxyhttp" {
return def
}
if def == "browserclient" {
return def
}
if c.Config == nil {
return typ
@ -63,10 +81,39 @@ func (c *Conf) SetType(label ...string) {
if strings.Contains(v, "client") {
c.Client = true
}
if c.Type == "server" || c.Type == "http" || c.Type == "client" || c.Type == "httpclient" || c.Type == "udpserver" || c.Type == "udpclient" || c.Type == "kcpclient" || c.Type == "kcpserver" {
switch c.Type {
case "server":
c.Type = v
case "http":
c.Type = v
case "client":
c.Type = v
case "httpclient":
c.Type = v
case "browserclient":
c.Type = v
case "udpserver":
c.Type = v
case "udpclient":
c.Type = v
case "eephttpd":
c.Type = v
case "outproxy":
c.Type = v
case "outproxyhttp":
c.Type = v
case "vpnserver":
c.Type = v
case "vpnclient":
c.Type = v
case "kcpclient":
c.Type = v
case "kcpserver":
c.Type = v
default:
c.Type = "browserclient"
}
} else {
c.Type = "server"
c.Type = "browserclient"
}
}

29
config/wwwdir.go Normal file
View File

@ -0,0 +1,29 @@
package i2ptunconf
//
// GetDir takes an argument and a default. If the argument differs from the
// default, the argument is always returned. If the argument and default are
// the same and the key exists, the key is returned. If the key is absent, the
// default is returned.
func (c *Conf) GetWWWDir(arg, def string, label ...string) string {
if arg != def {
return arg
}
if c.Config == nil {
return arg
}
if x, o := c.Get("wwwdir", label...); o {
return x
}
return arg
}
// SetDir sets the key save directory from the config file
func (c *Conf) SetWWWDir(label ...string) {
if v, ok := c.Get("wwwdir", label...); ok {
c.ServeDirectory = v
} else {
c.ServeDirectory = "./www"
}
}

View File

@ -13,7 +13,7 @@ usage:
flag needs an argument: -h
Usage of ./bin/samcatd:
-a string
Type of access list to use, can be "whitelist" "blacklist" or "none". (default "none")
Type of access list to use, can be "allowlist" "blocklist" or "none". (default "none")
-c Client proxy mode(true or false)
-conv string
Display the base32 and base64 values of a specified .i2pkeys file

View File

@ -53,12 +53,12 @@
[*] - i2cp.tcp.port 1-65535 7654 Router I2CP port. If the client is running in the same JVM as a router, this option is ignored, and the client connects to that router internally.
Default Description
[C] - i2cp.accessList null Comma- or space-separated list of Base64 peer Hashes used for either access list or blacklist. As of release 0.7.13.
[U] - i2cp.destination.sigType DSA_SHA1 Use the access list as a whitelist for incoming connections. The name or number of the signature type for a transient destination. As of release 0.9.12.
[C] - i2cp.enableAccessList false Use the access list as a whitelist for incoming connections. As of release 0.7.13.
[C] - i2cp.enableBlackList false Use the access list as a blacklist for incoming connections. As of release 0.7.13.
[C] - i2cp.accessList null Comma- or space-separated list of Base64 peer Hashes used for either access list or blocklist. As of release 0.7.13.
[U] - i2cp.destination.sigType DSA_SHA1 Use the access list as a allowlist for incoming connections. The name or number of the signature type for a transient destination. As of release 0.9.12.
[C] - i2cp.enableAccessList false Use the access list as a allowlist for incoming connections. As of release 0.7.13.
[C] - i2cp.enableBlackList false Use the access list as a blocklist for incoming connections. As of release 0.7.13.
[U] - i2p.streaming.answerPings true Whether to respond to incoming pings
[U] - i2p.streaming.blacklist null Comma- or space-separated list of Base64 peer Hashes to be blacklisted for incoming connections to ALL destinations in the context. This option must be set in the context properties, NOT in the createManager() options argument. Note that setting this in the router context will not affect clients outside the router in a separate JVM and context. As of release 0.9.3.
[U] - i2p.streaming.blocklist null Comma- or space-separated list of Base64 peer Hashes to be blocklisted for incoming connections to ALL destinations in the context. This option must be set in the context properties, NOT in the createManager() options argument. Note that setting this in the router context will not affect clients outside the router in a separate JVM and context. As of release 0.9.3.
[U] - i2p.streaming.bufferSize 64K How much transmit data (in bytes) will be accepted that hasn&#39;t been written out yet.
[U] - i2p.streaming.congestionAvoidanceGrowthRateFactor 1 When we&#39;re in congestion avoidance, we grow the window size at the rate of 1/(windowSize*factor). In standard TCP, window sizes are in bytes, while in I2P, window sizes are in messages. A higher number means slower growth.
[U] - i2p.streaming.connectDelay -1 How long to wait after instantiating a new con before actually attempting to connect. If this is &lt;= 0, connect immediately with no initial data. If greater than 0, wait until the output stream is flushed, the buffer fills, or that many milliseconds pass, and include any initial data with the SYN.

View File

@ -58,12 +58,12 @@ key:
[*] - i2cp.tcp.port 1-65535 7654 Router I2CP port. If the client is running in the same JVM as a router, this option is ignored, and the client connects to that router internally.
Default Description
[C] - i2cp.accessList null Comma- or space-separated list of Base64 peer Hashes used for either access list or blacklist. As of release 0.7.13.
[U] - i2cp.destination.sigType DSA_SHA1 Use the access list as a whitelist for incoming connections. The name or number of the signature type for a transient destination. As of release 0.9.12.
[C] - i2cp.enableAccessList false Use the access list as a whitelist for incoming connections. As of release 0.7.13.
[C] - i2cp.enableBlackList false Use the access list as a blacklist for incoming connections. As of release 0.7.13.
[C] - i2cp.accessList null Comma- or space-separated list of Base64 peer Hashes used for either access list or blocklist. As of release 0.7.13.
[U] - i2cp.destination.sigType DSA_SHA1 Use the access list as a allowlist for incoming connections. The name or number of the signature type for a transient destination. As of release 0.9.12.
[C] - i2cp.enableAccessList false Use the access list as a allowlist for incoming connections. As of release 0.7.13.
[C] - i2cp.enableBlackList false Use the access list as a blocklist for incoming connections. As of release 0.7.13.
[U] - i2p.streaming.answerPings true Whether to respond to incoming pings
[U] - i2p.streaming.blacklist null Comma- or space-separated list of Base64 peer Hashes to be blacklisted for incoming connections to ALL destinations in the context. This option must be set in the context properties, NOT in the createManager() options argument. Note that setting this in the router context will not affect clients outside the router in a separate JVM and context. As of release 0.9.3.
[U] - i2p.streaming.blocklist null Comma- or space-separated list of Base64 peer Hashes to be blocklisted for incoming connections to ALL destinations in the context. This option must be set in the context properties, NOT in the createManager() options argument. Note that setting this in the router context will not affect clients outside the router in a separate JVM and context. As of release 0.9.3.
[U] - i2p.streaming.bufferSize 64K How much transmit data (in bytes) will be accepted that hasn't been written out yet.
[U] - i2p.streaming.congestionAvoidanceGrowthRateFactor 1 When we're in congestion avoidance, we grow the window size at the rate of 1/(windowSize*factor). In standard TCP, window sizes are in bytes, while in I2P, window sizes are in messages. A higher number means slower growth.
[U] - i2p.streaming.connectDelay -1 How long to wait after instantiating a new con before actually attempting to connect. If this is <= 0, connect immediately with no initial data. If greater than 0, wait until the output stream is flushed, the buffer fills, or that many milliseconds pass, and include any initial data with the SYN.

View File

@ -4,7 +4,7 @@
<pre><code>flag needs an argument: -h
Usage of ./bin/samcatd:
-a string
Type of access list to use, can be &quot;whitelist&quot; &quot;blacklist&quot; or &quot;none&quot;. (default &quot;none&quot;)
Type of access list to use, can be &quot;allowlist&quot; &quot;blocklist&quot; or &quot;none&quot;. (default &quot;none&quot;)
-c Client proxy mode(true or false)
-conv string
Display the base32 and base64 values of a specified .i2pkeys file

View File

@ -26,7 +26,7 @@ i2cp.enableBlackList = false
[sam-forwarder-tcp-server]
type = server
host = 127.0.0.1
port = 8081
port = 7669
inbound.length = 2
outbound.length = 2
keys = tcpserver
@ -44,18 +44,18 @@ keys = tcpclient
type = udpserver
host = 127.0.0.1
port = 8084
#inbound.length = 6
inbound.length = 3
outbound.length = 3
keys = udpserver
#[sam-forwarder-udp-client]
#type = udpclient
#host = 127.0.0.1
#port = 8083
#inbound.length = 3
#outbound.length = 3
#destination = pointmeatatrealudpserveritwillbreakwithoutone.b32.i2p
#keys = udpclient
[sam-forwarder-udp-client]
type = udpclient
host = 127.0.0.1
port = 8083
inbound.length = 3
outbound.length = 3
destination = icdj5g5u4jwwyjoinucty223s2yrq6pzxcqfwmyrmkp7ssn2fjlq.b32.i2p
keys = udpclient
[sam-forwarder-tcp-http-server]
type = http
@ -72,3 +72,12 @@ keys = httpserver
#inbound.length = 3
#outbound.length = 3
#keys = proxy
[sam-forwarder-tcp-socks-outproxy]
type = client
host = 127.0.0.1
port = 8087
inbound.length = 2
outbound.length = 3
destination = 4oymiquy7qobjgx36tejs35zeqt24qpemsnzgtfeswmrw6csxbkq.b32.i2p
keys = tcpclient

View File

@ -1,5 +0,0 @@
eepHttpd, a standalone static web server for i2p
================================================
* [Official version:](https://github.com/eyedeekay/eephttpd)
* [See also:](https://eyedeekay.github.io/eephttpd/docs/EMBEDDING.md)

View File

@ -1,126 +0,0 @@
package main
/*
WARNING: This is not the official version of eephttpd. It is an older
verion I use to test new sam-forwarder features. It is not intended for
use.
*/
import (
"crypto/tls"
"flag"
"log"
"net/http"
"path/filepath"
)
import (
"github.com/eyedeekay/sam-forwarder/config"
"github.com/eyedeekay/sam-forwarder/tcp"
)
var cfg = &tls.Config{
MinVersion: tls.VersionTLS12,
CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
PreferServerCipherSuites: true,
CipherSuites: []uint16{
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_RSA_WITH_AES_256_CBC_SHA,
},
}
var (
host = flag.String("a", "127.0.0.1", "hostname to serve on")
port = flag.String("p", "7880", "port to serve locally on")
samhost = flag.String("sh", "127.0.0.1", "sam host to connect to")
samport = flag.String("sp", "7656", "sam port to connect to")
directory = flag.String("d", "./www", "the directory of static files to host(default ./www)")
sdirectory = flag.String("s", ".", "the directory to save the keys in(default ./)")
usei2p = flag.Bool("i", true, "save i2p keys(and thus destinations) across reboots")
servicename = flag.String("n", "static-eepSite", "name to give the tunnel(default static-eepSite)")
useCompression = flag.Bool("g", true, "Uze gzip(true or false)")
injectHeaders = flag.Bool("x", true, "Inject X-I2P-DEST headers")
accessListType = flag.String("l", "none", "Type of access list to use, can be \"whitelist\" \"blacklist\" or \"none\".")
encryptLeaseSet = flag.Bool("c", false, "Use an encrypted leaseset(true or false)")
allowZeroHop = flag.Bool("z", false, "Allow zero-hop, non-anonymous tunnels(true or false)")
reduceIdle = flag.Bool("r", false, "Reduce tunnel quantity when idle(true or false)")
reduceIdleTime = flag.Int("rt", 600000, "Reduce tunnel quantity after X (milliseconds)")
reduceIdleQuantity = flag.Int("rc", 3, "Reduce idle tunnel quantity to X (0 to 5)")
inLength = flag.Int("il", 3, "Set inbound tunnel length(0 to 7)")
outLength = flag.Int("ol", 3, "Set outbound tunnel length(0 to 7)")
inQuantity = flag.Int("iq", 8, "Set inbound tunnel quantity(0 to 15)")
outQuantity = flag.Int("oq", 8, "Set outbound tunnel quantity(0 to 15)")
inVariance = flag.Int("iv", 0, "Set inbound tunnel length variance(-7 to 7)")
outVariance = flag.Int("ov", 0, "Set outbound tunnel length variance(-7 to 7)")
inBackupQuantity = flag.Int("ib", 4, "Set inbound tunnel backup quantity(0 to 5)")
outBackupQuantity = flag.Int("ob", 4, "Set outbound tunnel backup quantity(0 to 5)")
iniFile = flag.String("f", "none", "Use an ini file for configuration")
useTLS = flag.Bool("t", false, "Generate or use an existing TLS certificate")
certFile = flag.String("m", "cert", "Certificate name to use")
)
func main() {
flag.Parse()
var forwarder *samforwarder.SAMForwarder
var err error
config := i2ptunconf.NewI2PBlankTunConf()
if *iniFile != "none" {
config, err = i2ptunconf.NewI2PTunConf(*iniFile)
}
config.TargetHost = config.GetHost(*host, "127.0.0.1")
config.TargetPort = config.GetPort(*port, "7880")
config.SaveFile = config.GetSaveFile(*usei2p, true)
config.SaveDirectory = config.GetDir(*sdirectory, "../")
config.SamHost = config.GetSAMHost(*samhost, "127.0.0.1")
config.SamPort = config.GetSAMPort(*samport, "7656")
config.TunName = config.GetKeys(*servicename, "static-eepSite")
config.InLength = config.GetInLength(*inLength, 3)
config.OutLength = config.GetOutLength(*outLength, 3)
config.InVariance = config.GetInVariance(*inVariance, 0)
config.OutVariance = config.GetOutVariance(*outVariance, 0)
config.InQuantity = config.GetInQuantity(*inQuantity, 6)
config.OutQuantity = config.GetOutQuantity(*outQuantity, 6)
config.InBackupQuantity = config.GetInBackups(*inBackupQuantity, 5)
config.OutBackupQuantity = config.GetOutBackups(*outBackupQuantity, 5)
config.EncryptLeaseSet = config.GetEncryptLeaseset(*encryptLeaseSet, false)
config.InAllowZeroHop = config.GetInAllowZeroHop(*allowZeroHop, false)
config.OutAllowZeroHop = config.GetOutAllowZeroHop(*allowZeroHop, false)
config.UseCompression = config.GetUseCompression(*useCompression, true)
config.ReduceIdle = config.GetReduceOnIdle(*reduceIdle, true)
config.ReduceIdleTime = config.GetReduceIdleTime(*reduceIdleTime, 600000)
config.ReduceIdleQuantity = config.GetReduceIdleQuantity(*reduceIdleQuantity, 2)
config.CloseIdleTime = config.GetCloseIdleTime(*reduceIdleTime, 600000)
config.AccessListType = config.GetAccessListType(*accessListType, "none")
config.Type = config.GetType(false, false, *injectHeaders, "server")
if forwarder, err = i2ptunconf.NewSAMForwarderFromConf(config); err != nil {
log.Fatal(err.Error())
}
go forwarder.Serve()
if *useTLS {
srv := &http.Server{
Addr: *host + ":" + *port,
Handler: http.FileServer(http.Dir(*directory)),
TLSConfig: cfg,
TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler), 0),
}
log.Printf("Serving %s on HTTPS port: %s\n\t and on \n%s", *directory, *port, forwarder.Base32())
log.Fatal(
srv.ListenAndServeTLS(
filepath.Join(*sdirectory+"/", *certFile+".crt"),
filepath.Join(*sdirectory+"/", *certFile+".key"),
),
)
} else {
log.Printf("Serving %s on HTTP port: %s\n\t and on \n%s", *directory, *port, forwarder.Base32())
log.Fatal(
http.ListenAndServe(
*host+":"+*port,
http.FileServer(http.Dir(*directory)),
),
)
}
}

View File

@ -1,33 +0,0 @@
package main package main
import ( import (
"flag" "flag"
"log" "log"
"net/http" "net/http"
) )
> import "github.com/eyedeekay/sam-forwarder"
>
func main() { func main() {
port := flag.String("p", "8101", "port to serve on") | port := flag.String("p", "8100", "port to serve on")
directory := flag.String("d", ".", "the directory of static file to host") directory := flag.String("d", ".", "the directory of static file to host")
flag.Parse() flag.Parse()
> forwarder, err := samforwarder.NewSAMForwarderFromOptions(
> samforwarder.SetHost("127.0.0.1"),
> samforwarder.SetPort(*port),
> samforwarder.SetSAMHost("127.0.0.1"),
> samforwarder.SetSAMPort("7656"),
> samforwarder.SetName("staticfiles"),
> )
> if err != nil {
> log.Fatal(err.Error())
> }
> go forwarder.Serve()
>
http.Handle("/", http.FileServer(http.Dir(*directory))) http.Handle("/", http.FileServer(http.Dir(*directory)))
log.Printf("Serving %s on HTTP port: %s\n", *directory, *port) | log.Printf("Serving %s on HTTP port: %s\n", *directory, *port, "and on",
log.Fatal(http.ListenAndServe(":"+*port, nil)) | forwarder.Base32()+".b32.i2p")
> log.Fatal(http.ListenAndServe("127.0.0.1:"+*port, nil))
} }

View File

@ -1,33 +0,0 @@
package main
import (
"flag"
"log"
"net/http"
)
import "github.com/eyedeekay/sam-forwarder"
func main() {
port := flag.String("p", "8100", "port to serve on")
directory := flag.String("d", ".", "the directory of static file to host")
flag.Parse()
forwarder, err := samforwarder.NewSAMForwarderFromOptions(
samforwarder.SetHost("127.0.0.1"),
samforwarder.SetPort(*port),
samforwarder.SetSAMHost("127.0.0.1"),
samforwarder.SetSAMPort("7656"),
samforwarder.SetName("staticfiles"),
)
if err != nil {
log.Fatal(err.Error())
}
go forwarder.Serve()
http.Handle("/", http.FileServer(http.Dir(*directory)))
log.Printf("Serving %s on HTTP port: %s\n", *directory, *port, "and on",
forwarder.Base32()+".b32.i2p")
log.Fatal(http.ListenAndServe("127.0.0.1:"+*port, nil))
}

View File

@ -1,194 +0,0 @@
<h1 id="samcatd---router-independent-tunnel-management-for-i2p">samcatd - Router-independent tunnel management for i2p</h1>
<p>samcatd is a daemon which runs a group of forwarding proxies to provide services over i2p independent of the router. It also serves as a generalized i2p networking utility for power-users. Its intended to be a Swiss-army knife for the SAM API.</p>
<h2 id="usage">usage:</h2>
<pre><code>flag needs an argument: -h
Usage of ./bin/samcatd:
-a string
Type of access list to use, can be &quot;whitelist&quot; &quot;blacklist&quot; or &quot;none&quot;. (default &quot;none&quot;)
-c Client proxy mode(true or false)
-conv string
Display the base32 and base64 values of a specified .i2pkeys file
-cr string
Encrypt/decrypt the key files with a passfile
-css string
custom CSS for web interface (default &quot;css/styles.css&quot;)
-ct int
Reduce tunnel quantity after X (milliseconds) (default 600000)
-d string
Directory to save tunnel configuration file in.
-de string
Destination to connect client&#39;s to by default.
-f string
Use an ini file for configuration(config file options override passed arguments for now.) (default &quot;none&quot;)
-h string
Target host(Host of service to forward to i2p) (default &quot;127.0.0.1&quot;)
-i string
Destination for client tunnels. Ignored for service tunnels. (default &quot;none&quot;)
-ib int
Set inbound tunnel backup quantity(0 to 5) (default 2)
-ih
Inject X-I2P-DEST headers
-il int
Set inbound tunnel length(0 to 7) (default 3)
-iq int
Set inbound tunnel quantity(0 to 15) (default 6)
-iv int
Set inbound tunnel length variance(-7 to 7)
-js string
custom JS for web interface (default &quot;js/scripts.js&quot;)
-k string
key for encrypted leaseset (default &quot;none&quot;)
-l Use an encrypted leaseset(true or false) (default true)
-littleboss string
instruct the littleboss:
start: start and manage this process using service name &quot;service-name&quot;
stop: signal the littleboss to shutdown the process
status: print statistics about the running littleboss
reload: restart the managed process using the executed binary
bypass: disable littleboss, run the program directly (default &quot;bypass&quot;)
-n string
Tunnel name, this must be unique but can be anything. (default &quot;forwarder&quot;)
-ob int
Set outbound tunnel backup quantity(0 to 5) (default 2)
-ol int
Set outbound tunnel length(0 to 7) (default 3)
-oq int
Set outbound tunnel quantity(0 to 15) (default 6)
-ov int
Set outbound tunnel length variance(-7 to 7)
-p string
Target port(Port of service to forward to i2p) (default &quot;8081&quot;)
-pk string
private key for encrypted leaseset (default &quot;none&quot;)
-psk string
private signing key for encrypted leaseset (default &quot;none&quot;)
-r Reduce tunnel quantity when idle(true or false)
-rq int
Reduce idle tunnel quantity to X (0 to 5) (default 3)
-rt int
Reduce tunnel quantity after X (milliseconds) (default 600000)
-s Start a tunnel with the passed parameters(Otherwise, they will be treated as default values.)
-sh string
SAM host (default &quot;127.0.0.1&quot;)
-sp string
SAM port (default &quot;7656&quot;)
-st string
Signature type
-t Use saved file and persist tunnel(If false, tunnel will not persist after program is stopped.
-tls string
(Currently inoperative. Target TLS port(HTTPS Port of service to forward to i2p)
-u UDP mode(true or false)
-w Start web administration interface
-wp string
Web port (default &quot;7957&quot;)
-x Close tunnel idle(true or false)
-z Uze gzip(true or false)
-zi
Allow zero-hop, non-anonymous tunnels in(true or false)
-zo
Allow zero-hop, non-anonymous tunnels out(true or false)</code></pre>
<h1 id="managing-samcatd-save-encryption-keys">managing samcatd save-encryption keys</h1>
<p>In order to keep from saving the .i2pkeys files in plaintext format, samcatd can optionally generate a key and encrypt the .i2pkeys files securely. Of course, to fully benefit from this arrangement, you need to move those keys away from the machine where the tunnel keys(the .i2pkeys file) are located, or protect them in some other way(sandboxing, etc). If you want to use encrypted .i2pkeys files, you can specify a key file to use with the -cr option on the terminal or with keyfile option in the .ini file.</p>
<h1 id="example-config---valid-for-both-ephsite-and-samcat">example config - valid for both ephsite and samcat</h1>
<p>Options are still being added, pretty much as fast as I can put them in. For up-to-the-minute options, see <a href="config/CHECKLIST.md">the checklist</a></p>
<p>(<strong>ephsite</strong> will only use top-level options, but they can be labeled or unlabeled)</p>
<p>(<strong>samcatd</strong> treats the first set of options it sees as the default, and does not start tunnels based on unlabeled options unless passed the -s flag.)</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode ini"><code class="sourceCode ini"><a class="sourceLine" id="cb2-1" title="1"></a>
<a class="sourceLine" id="cb2-2" title="2"><span class="co">## Defaults, these are only invoked with the -start option or if labeled tunnels</span></a>
<a class="sourceLine" id="cb2-3" title="3"><span class="co">## are not present(samcatd instructions). **THESE** are the correct config files</span></a>
<a class="sourceLine" id="cb2-4" title="4"><span class="co">## to use as defaults, and not the ones in ../sam-forwarder/tunnels.ini, which</span></a>
<a class="sourceLine" id="cb2-5" title="5"><span class="co">## are used for testing settings availability only.</span></a>
<a class="sourceLine" id="cb2-6" title="6"></a>
<a class="sourceLine" id="cb2-7" title="7"><span class="dt">inbound.length </span><span class="ot">=</span><span class="st"> </span><span class="dv">3</span></a>
<a class="sourceLine" id="cb2-8" title="8"><span class="dt">outbound.length </span><span class="ot">=</span><span class="st"> </span><span class="dv">3</span></a>
<a class="sourceLine" id="cb2-9" title="9"><span class="dt">inbound.lengthVariance </span><span class="ot">=</span><span class="st"> </span><span class="dv">0</span></a>
<a class="sourceLine" id="cb2-10" title="10"><span class="dt">outbound.lengthVariance </span><span class="ot">=</span><span class="st"> </span><span class="dv">0</span></a>
<a class="sourceLine" id="cb2-11" title="11"><span class="dt">inbound.backupQuantity </span><span class="ot">=</span><span class="st"> </span><span class="dv">3</span></a>
<a class="sourceLine" id="cb2-12" title="12"><span class="dt">outbound.backupQuantity </span><span class="ot">=</span><span class="st"> </span><span class="dv">3</span></a>
<a class="sourceLine" id="cb2-13" title="13"><span class="dt">inbound.quantity </span><span class="ot">=</span><span class="st"> </span><span class="dv">5</span></a>
<a class="sourceLine" id="cb2-14" title="14"><span class="dt">outbound.quantity </span><span class="ot">=</span><span class="st"> </span><span class="dv">5</span></a>
<a class="sourceLine" id="cb2-15" title="15"><span class="dt">inbound.allowZeroHop </span><span class="ot">=</span><span class="st"> </span><span class="kw">false</span></a>
<a class="sourceLine" id="cb2-16" title="16"><span class="dt">outbound.allowZeroHop </span><span class="ot">=</span><span class="st"> </span><span class="kw">false</span></a>
<a class="sourceLine" id="cb2-17" title="17"><span class="dt">i2cp.encryptLeaseSet </span><span class="ot">=</span><span class="st"> </span><span class="kw">false</span></a>
<a class="sourceLine" id="cb2-18" title="18"><span class="dt">gzip </span><span class="ot">=</span><span class="st"> </span><span class="kw">true</span></a>
<a class="sourceLine" id="cb2-19" title="19"><span class="dt">i2cp.reduceOnIdle </span><span class="ot">=</span><span class="st"> </span><span class="kw">true</span></a>
<a class="sourceLine" id="cb2-20" title="20"><span class="dt">i2cp.reduceIdleTime </span><span class="ot">=</span><span class="st"> </span><span class="dv">3000000</span></a>
<a class="sourceLine" id="cb2-21" title="21"><span class="dt">i2cp.reduceQuantity </span><span class="ot">=</span><span class="st"> </span><span class="dv">2</span></a>
<a class="sourceLine" id="cb2-22" title="22"><span class="dt">i2cp.enableWhiteList </span><span class="ot">=</span><span class="st"> </span><span class="kw">false</span></a>
<a class="sourceLine" id="cb2-23" title="23"><span class="dt">i2cp.enableBlackList </span><span class="ot">=</span><span class="st"> </span><span class="kw">false</span></a>
<a class="sourceLine" id="cb2-24" title="24"><span class="dt">keyfile </span><span class="ot">=</span><span class="st"> &quot;/usr/share/samcatd/samcatd&quot;</span></a>
<a class="sourceLine" id="cb2-25" title="25"></a>
<a class="sourceLine" id="cb2-26" title="26"><span class="co">#[sam-forwarder-tcp-server]</span></a>
<a class="sourceLine" id="cb2-27" title="27"><span class="co">#type = server</span></a>
<a class="sourceLine" id="cb2-28" title="28"><span class="co">#host = 127.0.0.1</span></a>
<a class="sourceLine" id="cb2-29" title="29"><span class="co">#port = 8081</span></a>
<a class="sourceLine" id="cb2-30" title="30"><span class="co">#inbound.length = 3</span></a>
<a class="sourceLine" id="cb2-31" title="31"><span class="co">#outbound.length = 3</span></a>
<a class="sourceLine" id="cb2-32" title="32"><span class="co">#keys = forwarder</span></a>
<a class="sourceLine" id="cb2-33" title="33"></a>
<a class="sourceLine" id="cb2-34" title="34"><span class="kw">[sam-forwarder-tcp-client]</span></a>
<a class="sourceLine" id="cb2-35" title="35"><span class="dt">type </span><span class="ot">=</span><span class="st"> client</span></a>
<a class="sourceLine" id="cb2-36" title="36"><span class="dt">host </span><span class="ot">=</span><span class="st"> </span><span class="dv">127</span><span class="st">.</span><span class="dv">0</span><span class="st">.</span><span class="fl">0.1</span></a>
<a class="sourceLine" id="cb2-37" title="37"><span class="dt">port </span><span class="ot">=</span><span class="st"> </span><span class="dv">8082</span></a>
<a class="sourceLine" id="cb2-38" title="38"><span class="dt">inbound.length </span><span class="ot">=</span><span class="st"> </span><span class="dv">3</span></a>
<a class="sourceLine" id="cb2-39" title="39"><span class="dt">outbound.length </span><span class="ot">=</span><span class="st"> </span><span class="dv">3</span></a>
<a class="sourceLine" id="cb2-40" title="40"><span class="dt">destination </span><span class="ot">=</span><span class="st"> i2p-projekt.i2p</span></a>
<a class="sourceLine" id="cb2-41" title="41"><span class="dt">keys </span><span class="ot">=</span><span class="st"> forwarder-two</span></a>
<a class="sourceLine" id="cb2-42" title="42"></a>
<a class="sourceLine" id="cb2-43" title="43"><span class="co">#[sam-forwarder-udp-server]</span></a>
<a class="sourceLine" id="cb2-44" title="44"><span class="co">#type = udpserver</span></a>
<a class="sourceLine" id="cb2-45" title="45"><span class="co">#host = 127.0.0.1</span></a>
<a class="sourceLine" id="cb2-46" title="46"><span class="co">#port = 8084</span></a>
<a class="sourceLine" id="cb2-47" title="47"><span class="co">#inbound.length = 6</span></a>
<a class="sourceLine" id="cb2-48" title="48"><span class="co">#outbound.length = 3</span></a>
<a class="sourceLine" id="cb2-49" title="49"><span class="co">#keys = forwarder-four</span></a>
<a class="sourceLine" id="cb2-50" title="50"></a>
<a class="sourceLine" id="cb2-51" title="51"><span class="co">#[sam-forwarder-udp-client]</span></a>
<a class="sourceLine" id="cb2-52" title="52"><span class="co">#type = udpclient</span></a>
<a class="sourceLine" id="cb2-53" title="53"><span class="co">#host = 127.0.0.1</span></a>
<a class="sourceLine" id="cb2-54" title="54"><span class="co">#port = 8083</span></a>
<a class="sourceLine" id="cb2-55" title="55"><span class="co">#inbound.length = 3</span></a>
<a class="sourceLine" id="cb2-56" title="56"><span class="co">#outbound.length = 3</span></a>
<a class="sourceLine" id="cb2-57" title="57"><span class="co">#destination = i2p-projekt.i2p</span></a>
<a class="sourceLine" id="cb2-58" title="58"><span class="co">#keys = forwarder-three</span></a>
<a class="sourceLine" id="cb2-59" title="59"></a>
<a class="sourceLine" id="cb2-60" title="60"><span class="co">#[sam-forwarder-tcp-http-server]</span></a>
<a class="sourceLine" id="cb2-61" title="61"><span class="co">#type = http</span></a>
<a class="sourceLine" id="cb2-62" title="62"><span class="co">#host = 127.0.0.1</span></a>
<a class="sourceLine" id="cb2-63" title="63"><span class="co">#port = 8085</span></a>
<a class="sourceLine" id="cb2-64" title="64"><span class="co">#inbound.length = 3</span></a>
<a class="sourceLine" id="cb2-65" title="65"><span class="co">#outbound.length = 3</span></a>
<a class="sourceLine" id="cb2-66" title="66"><span class="co">#keys = forwarder-five</span></a>
<a class="sourceLine" id="cb2-67" title="67"></a>
<a class="sourceLine" id="cb2-68" title="68"><span class="co">#[sam-forwarder-vpn-server]</span></a>
<a class="sourceLine" id="cb2-69" title="69"><span class="co">#type = udpserver</span></a>
<a class="sourceLine" id="cb2-70" title="70"><span class="co">#host = 127.0.0.1</span></a>
<a class="sourceLine" id="cb2-71" title="71"><span class="co">#port = 8084</span></a>
<a class="sourceLine" id="cb2-72" title="72"><span class="co">#inbound.length = 2</span></a>
<a class="sourceLine" id="cb2-73" title="73"><span class="co">#outbound.length = 2</span></a>
<a class="sourceLine" id="cb2-74" title="74"><span class="co">#inbound.backupQuantity = 3</span></a>
<a class="sourceLine" id="cb2-75" title="75"><span class="co">#outbound.backupQuantity = 3</span></a>
<a class="sourceLine" id="cb2-76" title="76"><span class="co">#inbound.quantity = 5</span></a>
<a class="sourceLine" id="cb2-77" title="77"><span class="co">#outbound.quantity = 5</span></a>
<a class="sourceLine" id="cb2-78" title="78"><span class="co">#i2cp.reduceOnIdle = true</span></a>
<a class="sourceLine" id="cb2-79" title="79"><span class="co">#i2cp.reduceIdleTime = 3000000</span></a>
<a class="sourceLine" id="cb2-80" title="80"><span class="co">#i2cp.reduceQuantity = 2</span></a>
<a class="sourceLine" id="cb2-81" title="81"><span class="co">#i2cp.closeOnIdle = false</span></a>
<a class="sourceLine" id="cb2-82" title="82"><span class="co">#keys = i2pvpnserver</span></a>
<a class="sourceLine" id="cb2-83" title="83"></a>
<a class="sourceLine" id="cb2-84" title="84"><span class="co">#[sam-forwarder-vpn-client]</span></a>
<a class="sourceLine" id="cb2-85" title="85"><span class="co">#type = udpclient</span></a>
<a class="sourceLine" id="cb2-86" title="86"><span class="co">#host = 127.0.0.1</span></a>
<a class="sourceLine" id="cb2-87" title="87"><span class="co">#port = 8085</span></a>
<a class="sourceLine" id="cb2-88" title="88"><span class="co">#inbound.length = 2</span></a>
<a class="sourceLine" id="cb2-89" title="89"><span class="co">#outbound.length = 2</span></a>
<a class="sourceLine" id="cb2-90" title="90"><span class="co">#inbound.backupQuantity = 3</span></a>
<a class="sourceLine" id="cb2-91" title="91"><span class="co">#outbound.backupQuantity = 3</span></a>
<a class="sourceLine" id="cb2-92" title="92"><span class="co">#inbound.quantity = 5</span></a>
<a class="sourceLine" id="cb2-93" title="93"><span class="co">#outbound.quantity = 5</span></a>
<a class="sourceLine" id="cb2-94" title="94"><span class="co">#i2cp.reduceOnIdle = true</span></a>
<a class="sourceLine" id="cb2-95" title="95"><span class="co">#i2cp.reduceIdleTime = 3000000</span></a>
<a class="sourceLine" id="cb2-96" title="96"><span class="co">#i2cp.reduceQuantity = 2</span></a>
<a class="sourceLine" id="cb2-97" title="97"><span class="co">#destination = adestinationisrequiredorbespecifiedatruntime.i2p</span></a>
<a class="sourceLine" id="cb2-98" title="98"><span class="co">#keys = i2pvpnclient</span></a></code></pre></div>

26
go.mod
View File

@ -4,23 +4,23 @@ go 1.12
require (
crawshaw.io/littleboss v0.0.0-20190317185602-8957d0aedcce
// github.com/RTradeLtd/go-anonvpn v0.0.0-20190914175831-ff09cd346471
github.com/boltdb/bolt v1.3.1 // indirect
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
github.com/boreq/friendlyhash v0.0.0-20190522010448-1ca64b3ca69e
github.com/eyedeekay/goSam v0.1.1-0.20190814204230-d4c9b8c57dd6 // indirect
github.com/eyedeekay/httptunnel v0.0.0-20190814204746-0081636585cd
github.com/cryptix/goSam v0.1.0 // indirect
github.com/eyedeekay/eephttpd v0.0.0-20190903000420-52f5a8485a4e
github.com/eyedeekay/httptunnel v0.0.0-20190831071439-0ff3d5f798fb
github.com/eyedeekay/i2pdig v0.0.0-20180718204453-a67cb46e2e5f // indirect
github.com/eyedeekay/outproxy v0.0.0-20190908174238-22bd71d43733
github.com/eyedeekay/portcheck v0.0.0-20190218044454-bb8718669680
github.com/eyedeekay/sam3 v0.0.0-20190730185140-f8d54526ea25
github.com/eyedeekay/sam3 v0.32.1
github.com/gtank/cryptopasta v0.0.0-20170601214702-1f550f6f2f69
github.com/justinas/nosurf v0.0.0-20190416172904-05988550ea18
github.com/kr/pty v1.1.8 // indirect
github.com/kr/pretty v0.2.0 // indirect
github.com/russross/blackfriday v2.0.0+incompatible // indirect
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
github.com/spf13/pflag v1.0.3 // indirect
github.com/zieckey/goini v0.0.0-20180118150432-0da17d361d26
github.com/zserge/lorca v0.1.8
github.com/zserge/webview v0.0.0-20180509070823-016c6ffd99f3
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 // indirect
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a // indirect
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect
golang.org/x/tools v0.0.0-20190814214036-f60b6e7d83f4 // indirect
github.com/zserge/webview v0.0.0-20190123072648-16c93bcaeaeb
gitlab.com/opennota/wd v0.0.0-20191124020556-236695b0ea63 // indirect
)
replace golang.org/x/lint v0.0.0 => github.com/golang/lint v0.0.0

85
go.sum Normal file
View File

@ -0,0 +1,85 @@
crawshaw.io/littleboss v0.0.0-20190317185602-8957d0aedcce h1:4VyRNGOpNgP9ioTYZ7ah3x8C28I7wsMt4Ao9nTXv2ec=
crawshaw.io/littleboss v0.0.0-20190317185602-8957d0aedcce/go.mod h1:TIbCAHgttUfOKudw59Il7Z0XIlitzo228/mtwMe4vPM=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/boreq/friendlyhash v0.0.0-20190522010448-1ca64b3ca69e h1:2q8XPjAYhXX8H71AoAPdgBrCUA3HPhC4ax8XHrTsY6I=
github.com/boreq/friendlyhash v0.0.0-20190522010448-1ca64b3ca69e/go.mod h1:y80zLCg0QS5u3fJKeF2rwpezcyZuCpZpbFcWv6Pn98w=
github.com/cryptix/go v1.3.1/go.mod h1:mFQotm9rTzptzvNjJM+1vSIDa/rVOVqMu0889GIXg70=
github.com/cryptix/goSam v0.1.0/go.mod h1:7ewkjhXT8V5RG07pvWUOHHtMahvGbeKlEv8ukUyRiTA=
github.com/d5/tengo v1.24.3 h1:wp44VW7fdfzMzIDT19tT5uNeGnm2UMd6s3TLAahrwSU=
github.com/d5/tengo v1.24.3/go.mod h1:VhLq8Q2QFhCIJO3NhvM934qOThykMqJi9y9Siqd1ocQ=
github.com/eyedeekay/eephttpd v0.0.0-20190903000420-52f5a8485a4e h1:YizBXWVO0QN/1vkcdXXGenBS0bJAHgJcG+2WO22im0Y=
github.com/eyedeekay/eephttpd v0.0.0-20190903000420-52f5a8485a4e/go.mod h1:wFPQsNBnY95LkuujFEZARo7slafRwoF0D97FFHBoZro=
github.com/eyedeekay/goSam v0.1.1-0.20190814204230-d4c9b8c57dd6 h1:+5eM/MhjGMWCGQCCqn9pb1bmvoRewweWhOaE6fA7kZ0=
github.com/eyedeekay/goSam v0.1.1-0.20190814204230-d4c9b8c57dd6/go.mod h1:kGTfZrncJ4CwMX3d1qA6bcMJTOcuTbOqgWg7WrFNAQ0=
github.com/eyedeekay/httptunnel v0.0.0-20190831065052-9eab288b8a82/go.mod h1:VeXBZz04xj4eUGAcD8ygn2WFxY/dAvRbSNYMWoDzMxc=
github.com/eyedeekay/httptunnel v0.0.0-20190831071439-0ff3d5f798fb h1:jxY4AjQDgkeG2WBop17iJrKcwulVF+fOakOWSiIVcwY=
github.com/eyedeekay/httptunnel v0.0.0-20190831071439-0ff3d5f798fb/go.mod h1:SnCAM9CskhwSFkzDfh+H5yNTbvhcTeKekkuX0ejCcSk=
github.com/eyedeekay/i2pdig v0.0.0-20180718204453-a67cb46e2e5f/go.mod h1:Zp2JSsndmRykjDGbNS5QHnCYCLnOeYFvwuZFwsATz8k=
github.com/eyedeekay/outproxy v0.0.0-20190908174238-22bd71d43733 h1:bm9QcH6cMUUKQ9cOiTgTVLaU9FwhvwecxCSZepKTMcU=
github.com/eyedeekay/outproxy v0.0.0-20190908174238-22bd71d43733/go.mod h1:jUBr6XRbiuUBe/sSbVdO5upU4mp8842bdpXDsQY54Rc=
github.com/eyedeekay/portcheck v0.0.0-20190218044454-bb8718669680 h1:wZxtUXCp5cOF5gB6PGeUny7ljGFcK6YKFfU7Sf8JBLc=
github.com/eyedeekay/portcheck v0.0.0-20190218044454-bb8718669680/go.mod h1:8VVIH19/CU2VFJB8P6e58Mo9nvDqqKgllS0oQY3F83U=
github.com/eyedeekay/ramp v0.0.0-20190429201811-305b382042ab h1:EfTRHxGSbiaEyxNzvKRBWVIDw3mD8xXGxj4gvwFzY7Q=
github.com/eyedeekay/ramp v0.0.0-20190429201811-305b382042ab/go.mod h1:h7mvUAMgZ/rtRDUOkvKTK+8LnDMeUhJSoa5EPdB51fc=
github.com/eyedeekay/sam-forwarder v0.0.0-20190814201550-7c0d7cb0d56c/go.mod h1:Ptrm1d4a3KC5/cN264Gn6OntYOmcuJ8Pkyd7+hA01gw=
github.com/eyedeekay/sam-forwarder v0.0.0-20190831071254-d67c0c0e311f/go.mod h1:u4K8aGwSIuMSQ/OzsH7zkshnEvCQgUupfexLXZIjsDI=
github.com/eyedeekay/sam-forwarder v0.0.0-20190905212604-029317222e15/go.mod h1:kFP6jkqHUTGGW/nMUZLnRonkPWE9fyEc8/eSU1CqTFg=
github.com/eyedeekay/sam3 v0.0.0-20190613034117-99ad6522ebe3/go.mod h1:Vrxh+71E3HVYqyRlT5Jg+E26sSuu8UNTLB4p8qyT408=
github.com/eyedeekay/sam3 v0.0.0-20190730185140-f8d54526ea25/go.mod h1:Y3igFVzN4ybqkkpfUWULGhw7WRp8lieq0ORXbLBbcZM=
github.com/eyedeekay/sam3 v0.32.1 h1:xaquh9Sxyuxh0SKyv3Gh6wXcZ5QAfWC4Iz4IsjVSESk=
github.com/eyedeekay/sam3 v0.32.1/go.mod h1:Y3igFVzN4ybqkkpfUWULGhw7WRp8lieq0ORXbLBbcZM=
github.com/go-kit/kit v0.6.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-stack/stack v1.7.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gtank/cryptopasta v0.0.0-20170601214702-1f550f6f2f69 h1:7xsUJsB2NrdcttQPa7JLEaGzvdbk7KvfrjgHZXOQRo0=
github.com/gtank/cryptopasta v0.0.0-20170601214702-1f550f6f2f69/go.mod h1:YLEMZOtU+AZ7dhN9T/IpGhXVGly2bvkJQ+zxj3WeVQo=
github.com/justinas/nosurf v0.0.0-20190416172904-05988550ea18 h1:ci3v0mUqcCewO25ntt7hprt2ZMNA0AWI6s6qV0rSpc0=
github.com/justinas/nosurf v0.0.0-20190416172904-05988550ea18/go.mod h1:Aucr5I5chr4OCuuVB4LTuHVrKHBuyRSo7vM2hqrcb7E=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/miolini/datacounter v0.0.0-20171104152933-fd4e42a1d5e0/go.mod h1:P6fDJzlxN+cWYR09KbE9/ta+Y6JofX9tAUhJpWkWPaM=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/russross/blackfriday v2.0.0+incompatible/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/zieckey/goini v0.0.0-20180118150432-0da17d361d26 h1:E0lEWrifmR0ACbGf5PLji1XbW6rtIXLHCXO/YOqi0AE=
github.com/zieckey/goini v0.0.0-20180118150432-0da17d361d26/go.mod h1:TQpdgg7I9+PFIkatlx/dnZyZb4iZyCUx1HJj4rXi3+E=
github.com/zserge/lorca v0.1.8 h1:gZwyvesmaoGCwxF5NssI6pdydXkCVHOoHw2nks/PBRs=
github.com/zserge/lorca v0.1.8/go.mod h1:gTrVdXKyWxNhc8aUb1Uu3s0mY343arR1T6jUtxmBxR8=
github.com/zserge/webview v0.0.0-20190123072648-16c93bcaeaeb h1:zVjnyZIM7UtkG3dNckiudIm+TUHkZqi5xlVQPd3J6/c=
github.com/zserge/webview v0.0.0-20190123072648-16c93bcaeaeb/go.mod h1:a1CV8KR4Dd1eP2g+mEijGOp+HKczwdKHWyx0aPHKvo4=
gitlab.com/golang-commonmark/html v0.0.0-20180917080848-cfaf75183c4a h1:Ax7kdHNICZiIeFpmevmaEWb0Ae3BUj3zCTKhZHZ+zd0=
gitlab.com/golang-commonmark/html v0.0.0-20180917080848-cfaf75183c4a/go.mod h1:JT4uoTz0tfPoyVH88GZoWDNm5NHJI2VbUW+eyPClueI=
gitlab.com/golang-commonmark/linkify v0.0.0-20180917065525-c22b7bdb1179 h1:rbON2KwBnWuFMlSHM8LELLlwroDRZw6xv0e6il6e5dk=
gitlab.com/golang-commonmark/linkify v0.0.0-20180917065525-c22b7bdb1179/go.mod h1:Gn+LZmCrhPECMD3SOKlE+BOHwhOYD9j7WT9NUtkCrC8=
gitlab.com/golang-commonmark/markdown v0.0.0-20181102083822-772775880e1f h1:jwXy/CsM4xS2aoiF2fHAlukmInWhd2TlWB+HDCyvzKc=
gitlab.com/golang-commonmark/markdown v0.0.0-20181102083822-772775880e1f/go.mod h1:SIHlEr9462fpIfTrVWf3GqQDxnA65Vm3BMMsUtuA6W0=
gitlab.com/golang-commonmark/mdurl v0.0.0-20180912090424-e5bce34c34f2 h1:wD/sPUgx2QJFPTyXZpJnLaROolfeKuruh06U4pRV0WY=
gitlab.com/golang-commonmark/mdurl v0.0.0-20180912090424-e5bce34c34f2/go.mod h1:wQk4rLkWrdOPjUAtqJRJ10hIlseLSVYWP95PLrjDF9s=
gitlab.com/golang-commonmark/puny v0.0.0-20180912090636-2cd490539afe h1:5kUPFAF52umOUPH12MuNUmyVTseJRNBftDl/KfsvX3I=
gitlab.com/golang-commonmark/puny v0.0.0-20180912090636-2cd490539afe/go.mod h1:P9LSM1KVzrIstFgUaveuwiAm8PK5VTB3yJEU8kqlbrU=
gitlab.com/opennota/wd v0.0.0-20191124020556-236695b0ea63/go.mod h1:n0SNS6rmmsb705EuaYk2RDZyy+pcmwEAuwQkTOOjsu8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 h1:Gv7RPwsi3eZ2Fgewe3CBsuOebPwO27PoXzRpJPsvSSM=
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20181102091132-c10e9556a7bc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190830142957-1e83adbbebd0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190830223141-573d9926052a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@ -74,20 +74,24 @@ func (m *TunnelHandlerMux) Home(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "<!DOCTYPE html>\n")
fmt.Fprintf(w, "<html>\n")
fmt.Fprintf(w, "<head>\n")
fmt.Fprintf(w, " <title>")
fmt.Fprintf(w, "samcatd")
fmt.Fprintf(w, " </title>")
fmt.Fprintf(w, " <link rel=\"stylesheet\" href=\"/styles.css\">")
fmt.Fprintf(w, "</head>\n")
fmt.Fprintf(w, "<body>\n")
fmt.Fprintf(w, "<h1>\n")
w.Write([]byte(fmt.Sprintf("<a href=\"/index.html\">Welcome %s! you are serving %d tunnels. </a>\n", m.user, len(m.tunnels))))
fmt.Fprintf(w, "</h1>\n")
fmt.Fprintf(w, " <div id=\"toggleall\" class=\"global control\">\n")
fmt.Fprintf(w, " <a href=\"#\" onclick=\"toggle_visibility_class('%s');\">Show/Hide %s</a>\n", "prop", "all")
fmt.Fprintf(w, " </div>\n")
fmt.Fprintf(w, " <body>\n")
fmt.Fprintf(w, " <h1>\n")
w.Write([]byte(fmt.Sprintf(" <a href=\"/index.html\">Welcome %s! you are serving %d tunnels. </a>\n", m.user, len(m.tunnels))))
//fmt.Fprintf(w, "")
fmt.Fprintf(w, " </h1>\n")
fmt.Fprintf(w, " <div id=\"toggleall\" class=\"global control\">\n")
fmt.Fprintf(w, " <a href=\"#\" onclick=\"toggle_visibility_class('%s');\">Show/Hide %s</a>\n", "prop", "all")
fmt.Fprintf(w, " </div>\n")
for _, tunnel := range m.Tunnels() {
tunnel.ServeHTTP(w, r2)
}
fmt.Fprintf(w, " <script src=\"/scripts.js\"></script>\n")
fmt.Fprintf(w, "</body>\n")
fmt.Fprintf(w, " <script src=\"/scripts.js\"></script>\n")
fmt.Fprintf(w, " </body>\n")
fmt.Fprintf(w, "</html>\n")
}

View File

@ -60,29 +60,6 @@ func (m *TunnelHandlerMux) HandlerWrapper(h http.Handler) http.Handler {
})
}
func (m *TunnelHandlerMux) ColorHeader(h http.Handler, r *http.Request, w http.ResponseWriter) {
if !strings.HasSuffix(r.URL.Path, "color") {
h.ServeHTTP(w, r)
} else {
fmt.Fprintf(w, "<!DOCTYPE html>\n")
fmt.Fprintf(w, "<html>\n")
fmt.Fprintf(w, "<head>\n")
fmt.Fprintf(w, " <link rel=\"stylesheet\" href=\"/styles.css\">")
fmt.Fprintf(w, "</head>\n")
fmt.Fprintf(w, "<body>\n")
fmt.Fprintf(w, "<h1>\n")
w.Write([]byte(fmt.Sprintf("<a href=\"/index.html\">Welcome %s! you are serving %d tunnels. </a>\n", m.user, len(m.tunnels))))
fmt.Fprintf(w, "</h1>\n")
fmt.Fprintf(w, " <div id=\"toggleall\" class=\"global control\">\n")
fmt.Fprintf(w, " <a href=\"#\" onclick=\"toggle_visibility_class('%s');\">Show/Hide %s</a>\n", "prop", "all")
fmt.Fprintf(w, " </div>\n")
h.ServeHTTP(w, r)
fmt.Fprintf(w, " <script src=\"/scripts.js\"></script>\n")
fmt.Fprintf(w, "</body>\n")
fmt.Fprintf(w, "</html>\n")
}
}
func (t *TunnelHandlerMux) Tunnels() []*TunnelHandler {
return t.tunnels
}

View File

@ -1,5 +1,11 @@
package samtunnelhandler
import (
"fmt"
"net/http"
"strings"
)
func DefaultCSS() string {
return `.server {
width: 63%;
@ -15,6 +21,13 @@ func DefaultCSS() string {
float: left;
overflow-wrap: break-word;
}
.tcpclient {
width: 63%;
min-height: 15%;
background-color: #2D4470;
float: left;
overflow-wrap: break-word;
}
.http {
width: 63%;
min-height: 15%;
@ -36,6 +49,20 @@ func DefaultCSS() string {
float: left;
overflow-wrap: break-word;
}
.outproxy {
width: 63%;
min-height: 15%;
background-color: #265ea7;
float: left;
overflow-wrap: break-word;
}
.outproxyhttp {
width: 63%;
min-height: 15%;
background-color: #265ea7;
float: left;
overflow-wrap: break-word;
}
.udpclient {
width: 63%;
min-height: 15%;
@ -164,3 +191,70 @@ function toggle_visibility_class(id) {
toggle_visibility_class("prop")
`
}
func (t *TunnelHandler) ColorSpan(shortid string) string {
r := fmt.Sprintf(" <span id=\"toggle%s\" class=\"control\">\n", t.SAMTunnel.ID())
r += fmt.Sprintf(" <a href=\"#\" onclick=\"toggle_visibility_class('%s');\"> Show/Hide %s</a><br>\n", t.SAMTunnel.ID(), t.SAMTunnel.ID())
r += fmt.Sprintf(" <a href=\"/%s/color\">Tunnel page</a>\n", t.SAMTunnel.ID())
r += fmt.Sprintf(" </span>\n")
return r
}
func (t *TunnelHandler) ColorForm(shortid, tuntype string) string {
r := fmt.Sprintf(" </div>\n\n")
r += fmt.Sprintf(" <div id=\"%s\" class=\"%s control panel\" >", shortid+".control", tuntype)
r += fmt.Sprintf(" <form class=\"linkstyle\" name=\"start\" action=\"/%s\" method=\"post\">", shortid)
r += fmt.Sprintf(" <input class=\"linkstyle\" type=\"hidden\" value=\"start\" name=\"action\" />")
r += fmt.Sprintf(" <input class=\"linkstyle\" type=\"submit\" value=\".[START]\">")
r += fmt.Sprintf(" </form>")
r += fmt.Sprintf(" <form class=\"linkstyle\" name=\"stop\" action=\"/%s\" method=\"post\">", shortid)
r += fmt.Sprintf(" <input class=\"linkstyle\" type=\"hidden\" value=\"stop\" name=\"action\" />")
r += fmt.Sprintf(" <input class=\"linkstyle\" type=\"submit\" value=\".[STOP].\">")
r += fmt.Sprintf(" </form>")
r += fmt.Sprintf(" <form class=\"linkstyle\" name=\"restart\" action=\"/%s\" method=\"post\">", shortid)
r += fmt.Sprintf(" <input class=\"linkstyle\" type=\"hidden\" value=\"restart\" name=\"action\" />")
r += fmt.Sprintf(" <input class=\"linkstyle\" type=\"submit\" value=\"[RESTART].\">")
r += fmt.Sprintf(" </form>")
r += fmt.Sprintf(" <div id=\"%s.status\" class=\"%s status\">.[STATUS].</div>", shortid, shortid)
r += fmt.Sprintf(" </div>\n\n")
return r
}
func (t *TunnelHandler) ColorWrap(longid, shortid, key, tuntype, prop, value string) string {
r := fmt.Sprintf(" <div id=\"%s\" class=\"%s %s %s %s\" >\n", longid, shortid, key, tuntype, prop)
r += fmt.Sprintf(" <span id=\"%s\" class=\"key\">%s</span>=", longid, key)
r += fmt.Sprintf(" <textarea id=\"%s\" rows=\"1\" class=\"value\">%s</textarea>\n", longid, value)
r += fmt.Sprintf(" </div>\n\n")
return r
}
func (t *TunnelHandler) ColorDiv(shortid, tuntype string) string {
return fmt.Sprintf(" <div id=\"%s\" class=\"%s\" >", t.SAMTunnel.ID(), t.SAMTunnel.GetType())
}
func (m *TunnelHandlerMux) ColorHeader(h http.Handler, r *http.Request, w http.ResponseWriter) {
if !strings.HasSuffix(r.URL.Path, "color") {
h.ServeHTTP(w, r)
} else {
fmt.Fprintf(w, "<!DOCTYPE html>\n")
fmt.Fprintf(w, "<html>\n")
fmt.Fprintf(w, "<head>\n")
fmt.Fprintf(w, " <link rel=\"stylesheet\" href=\"/styles.css\">")
fmt.Fprintf(w, "</head>\n")
fmt.Fprintf(w, "<body>\n")
fmt.Fprintf(w, "<h1>\n")
w.Write([]byte(fmt.Sprintf("<a href=\"/index.html\">Welcome %s! you are serving %d tunnels. </a>\n", m.user, len(m.tunnels))))
fmt.Fprintf(w, "</h1>\n")
fmt.Fprintf(w, " <div id=\"toggleall\" class=\"global control\">\n")
fmt.Fprintf(w, " <a href=\"#\" onclick=\"toggle_visibility_class('%s');\">Show/Hide %s</a>\n", "prop", "all")
fmt.Fprintf(w, " </div>\n")
h.ServeHTTP(w, r)
fmt.Fprintf(w, " <script src=\"/scripts.js\"></script>\n")
fmt.Fprintf(w, "</body>\n")
fmt.Fprintf(w, "</html>\n")
}
}

View File

@ -27,14 +27,18 @@ func (t *TunnelHandler) Printdivf(id, key, value string, rw http.ResponseWriter,
if key != "TunName" {
prop = "prop"
}
if strings.HasSuffix(req.URL.Path, "color") {
fmt.Fprintf(rw, " <div id=\"%s\" class=\"%s %s %s %s\" >\n", ID, t.SAMTunnel.ID(), key, t.SAMTunnel.GetType(), prop)
fmt.Fprintf(rw, " <span id=\"%s\" class=\"key\">%s</span>=", ID, key)
fmt.Fprintf(rw, " <textarea id=\"%s\" rows=\"1\" class=\"value\">%s</textarea>\n", ID, value)
fmt.Fprintf(rw, " </div>\n\n")
} else {
fmt.Fprintf(rw, "%s=%s\n", ID, t.SAMTunnel.ID())
fmt.Fprintf(rw, t.ColorWrap(ID, t.SAMTunnel.ID(), key, t.SAMTunnel.GetType(), prop, value))
}
func (t *TunnelHandler) Printf(id, key, value string, rw http.ResponseWriter, req *http.Request) {
if key == "" || value == "" {
return
}
ID := t.SAMTunnel.ID()
if id != "" {
ID = t.SAMTunnel.ID() + "." + id
}
fmt.Fprintf(rw, "%s=%s\n", ID, t.SAMTunnel.ID())
}
func PropSort(props map[string]string) []string {
@ -46,7 +50,7 @@ func PropSort(props map[string]string) []string {
return slice
}
func (t *TunnelHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
func (t *TunnelHandler) ControlForm(rw http.ResponseWriter, req *http.Request) {
if err := req.ParseForm(); err == nil {
if action := req.PostFormValue("action"); action != "" {
var err error
@ -87,47 +91,31 @@ func (t *TunnelHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
}
}
}
}
func (t *TunnelHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
t.ControlForm(rw, req)
if strings.HasSuffix(req.URL.Path, "color") {
fmt.Fprintf(rw, " <div id=\"%s\" class=\"%s\" >", t.SAMTunnel.ID(), t.SAMTunnel.GetType())
}
t.Printdivf(t.SAMTunnel.ID(), "TunName", t.SAMTunnel.ID(), rw, req)
if strings.HasSuffix(req.URL.Path, "color") {
fmt.Fprintf(rw, " <span id=\"toggle%s\" class=\"control\">\n", t.SAMTunnel.ID())
fmt.Fprintf(rw, " <a href=\"#\" onclick=\"toggle_visibility_class('%s');\"> Show/Hide %s</a><br>\n", t.SAMTunnel.ID(), t.SAMTunnel.ID())
fmt.Fprintf(rw, " <a href=\"/%s/color\">Tunnel page</a>\n", t.SAMTunnel.ID())
fmt.Fprintf(rw, " </span>\n")
}
for _, value := range PropSort(t.SAMTunnel.Props()) {
key := strings.SplitN(value, "=", 2)[0]
val := strings.SplitN(value, "=", 2)[1]
if key != "TunName" {
t.Printdivf(key, key, val, rw, req)
fmt.Fprintf(rw, t.ColorDiv(t.SAMTunnel.ID(), t.SAMTunnel.GetType()))
t.Printdivf(t.SAMTunnel.ID(), "TunName", t.SAMTunnel.ID(), rw, req)
fmt.Fprintf(rw, t.ColorSpan(t.SAMTunnel.ID()))
for _, value := range PropSort(t.SAMTunnel.Props()) {
key := strings.SplitN(value, "=", 2)[0]
val := strings.SplitN(value, "=", 2)[1]
if key != "TunName" {
t.Printdivf(key, key, val, rw, req)
}
}
fmt.Fprintf(rw, t.ColorForm(t.SAMTunnel.ID(), t.SAMTunnel.GetType()))
} else {
t.Printf(t.SAMTunnel.ID(), "TunName", t.SAMTunnel.ID(), rw, req)
for _, value := range PropSort(t.SAMTunnel.Props()) {
key := strings.SplitN(value, "=", 2)[0]
val := strings.SplitN(value, "=", 2)[1]
if key != "TunName" {
t.Printf(key, key, val, rw, req)
}
}
}
if strings.HasSuffix(req.URL.Path, "color") {
fmt.Fprintf(rw, " </div>\n\n")
fmt.Fprintf(rw, " <div id=\"%s\" class=\"%s control panel\" >", t.SAMTunnel.ID()+".control", t.SAMTunnel.GetType())
fmt.Fprintf(rw, " <form class=\"linkstyle\" name=\"start\" action=\"/%s\" method=\"post\">", t.SAMTunnel.ID())
fmt.Fprintf(rw, " <input class=\"linkstyle\" type=\"hidden\" value=\"start\" name=\"action\" />")
fmt.Fprintf(rw, " <input class=\"linkstyle\" type=\"submit\" value=\".[START]\">")
fmt.Fprintf(rw, " </form>")
fmt.Fprintf(rw, " <form class=\"linkstyle\" name=\"stop\" action=\"/%s\" method=\"post\">", t.SAMTunnel.ID())
fmt.Fprintf(rw, " <input class=\"linkstyle\" type=\"hidden\" value=\"stop\" name=\"action\" />")
fmt.Fprintf(rw, " <input class=\"linkstyle\" type=\"submit\" value=\".[STOP].\">")
fmt.Fprintf(rw, " </form>")
fmt.Fprintf(rw, " <form class=\"linkstyle\" name=\"restart\" action=\"/%s\" method=\"post\">", t.SAMTunnel.ID())
fmt.Fprintf(rw, " <input class=\"linkstyle\" type=\"hidden\" value=\"restart\" name=\"action\" />")
fmt.Fprintf(rw, " <input class=\"linkstyle\" type=\"submit\" value=\"[RESTART].\">")
fmt.Fprintf(rw, " </form>")
fmt.Fprintf(rw, " <div id=\"%s.status\" class=\"%s status\">.[STATUS].</div>", t.SAMTunnel.ID(), t.SAMTunnel.ID())
fmt.Fprintf(rw, " </div>\n\n")
}
}

View File

@ -1,34 +1,55 @@
package samtunnel
import (
"github.com/eyedeekay/sam-forwarder/config"
"github.com/eyedeekay/sam3/i2pkeys"
)
// SAMTunnel is an interface comprehensively representing an I2P tunnel over SAM
// in Go
type SAMTunnel interface {
// Config returns the appropriate underlying config object all options, or
// the common options passed into a compound tunnel.
Config() *i2ptunconf.Conf
// Tunnel Options
GetType() string // Get the type of the tunnel in use(server, client, http, udp, etc)
Print() string // Print all the tunnel options as a string
Props() map[string]string //Get a full list of tunnel properties as a map for user display/analysis
Search(search string) string //Search the Props for a common term
Target() string //The address of the local client or service to forward with a SAM tunnel
ID() string //The user-chosen tunnel ID
// GetType Get the type of the tunnel in use(server, client, http, udp, etc)
GetType() string
// Print all the tunnel options as a string
Print() string
// Props Get a full list of tunnel properties as a map for user display/analysis
Props() map[string]string
//Search the Props for a common term
Search(search string) string
//Target The address of the local client or service to forward with a SAM tunnel
Target() string
//ID The user-chosen tunnel name
ID() string
//Destination() string
// Key handling
Base32() string // Get the .b32.i2p address of your service
Base32Readable() string // Create a more-readable representation of the .b32.i2p address using English words
Base64() string // Get the public base64 address of your I2P service
Keys() i2pkeys.I2PKeys // Get all the parts of the keys to your I2P service
// Get the .b32.i2p address of your service
Base32() string
// Create a more-readable representation of the .b32.i2p address using English words
Base32Readable() string
// Get the public base64 address of your I2P service
Base64() string
// Get all the parts of the keys to your I2P service
Keys() i2pkeys.I2PKeys
// Service Management
Load() (SAMTunnel, error) // Prepare tunnel keys and tunnel options
Serve() error // Start the tunnel
Close() error // Stop the tunnel and close all connections
Cleanup() // Stop the tunnel but leave the sockets alone for now
Up() bool // Return "true" if the tunnel is ready to go up.
// Prepare tunnel keys and tunnel options
Load() (SAMTunnel, error)
// Start the tunnel
Serve() error
// Stop the tunnel and close all connections
Close() error
// Stop the tunnel but leave the sockets alone for now
Cleanup()
// Return "true" if the tunnel is ready to go up.
Up() bool
}
// WebUI is an interface which is used to generate a minimal UI. Open to suggestions.
type WebUI interface {
Title() string
URL() string

View File

@ -13,15 +13,7 @@ type ManagerOption func(*SAMManager) error
//SetManagerFilePath sets the host of the SAMManager's SAM bridge
func SetManagerFilePath(s string) func(*SAMManager) error {
return func(c *SAMManager) error {
c.FilePath = s
return nil
}
}
//SetManagerSaveFile tells the router to use an encrypted leaseset
func SetManagerSaveFile(b bool) func(*SAMManager) error {
return func(c *SAMManager) error {
c.save = b
c.config.FilePath = s
return nil
}
}

View File

@ -12,15 +12,14 @@ import (
import (
"github.com/eyedeekay/portcheck"
"github.com/eyedeekay/sam-forwarder/config"
"github.com/eyedeekay/sam-forwarder/config/helpers"
"github.com/eyedeekay/sam-forwarder/handler"
"github.com/justinas/nosurf"
)
type SAMManager struct {
FilePath string
save bool
start bool
config *i2ptunconf.Conf
start bool
config *i2ptunconf.Conf
tunName string
@ -89,11 +88,10 @@ var runningUser = User()
func NewSAMManagerFromOptions(opts ...func(*SAMManager) error) (*SAMManager, error) {
var s SAMManager
s.FilePath = ""
s.save = true
s.config = i2ptunconf.NewI2PBlankTunConf()
s.config.FilePath = ""
s.start = false
s.UseWeb = true
s.config = i2ptunconf.NewI2PBlankTunConf()
s.ServerHost = "localhost"
s.ServerPort = "8081"
s.SamHost = "localhost"
@ -110,6 +108,7 @@ func NewSAMManagerFromOptions(opts ...func(*SAMManager) error) (*SAMManager, err
return nil, err
}
}
log.Println("MANAGER INITIALIZING")
if port, err := strconv.Atoi(s.WebPort); err != nil {
log.Println("Error:", err)
return nil, err
@ -121,77 +120,100 @@ func NewSAMManagerFromOptions(opts ...func(*SAMManager) error) (*SAMManager, err
}
}
s.handlerMux = samtunnelhandler.NewTunnelHandlerMux(s.WebHost, s.WebPort, s.config.UserName, s.config.Password, s.cssFile, s.jsFile)
log.Println("tunnel settings", s.ServerHost, s.ServerPort, s.SamHost, s.SamPort)
log.Println("tunnel settings from", s.config.FilePath, "are", s.ServerHost, s.ServerPort, s.SamHost, s.SamPort)
var err error
if s.FilePath != "" {
s.config, err = i2ptunconf.NewI2PTunConf(s.FilePath)
if s.config.FilePath != "" {
s.config, err = i2ptunconf.NewI2PTunConf(s.config.FilePath)
s.config.TargetHost = s.config.GetHost(s.ServerHost, "127.0.0.1")
s.config.TargetPort = s.config.GetPort(s.ServerPort, "8081")
if err != nil {
return nil, err
}
log.Println("Manager found Labels", s.config.Labels)
for _, label := range s.config.Labels {
log.Println("Processing tunnel for label", label)
if t, e := s.config.Get("type", label); e {
switch t {
case "http":
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunconf.NewSAMForwarderFromConfig(s.FilePath, s.SamHost, s.SamPort, label)); e == nil {
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMForwarderFromConfig(s.config.FilePath, s.SamHost, s.SamPort, label)); e == nil {
log.Println("found http under", label)
s.handlerMux = s.handlerMux.Append(f)
} else {
return nil, e
}
case "httpclient":
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunconf.NewSAMHTTPClientFromConfig(s.FilePath, s.SamHost, s.SamPort, label)); e == nil {
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMHTTPClientFromConfig(s.config.FilePath, s.SamHost, s.SamPort, label)); e == nil {
log.Println("found http under", label)
s.handlerMux = s.handlerMux.Append(f)
} else {
return nil, e
}
case "server":
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunconf.NewSAMForwarderFromConfig(s.FilePath, s.SamHost, s.SamPort, label)); e == nil {
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMForwarderFromConfig(s.config.FilePath, s.SamHost, s.SamPort, label)); e == nil {
log.Println("found server under", label)
s.handlerMux = s.handlerMux.Append(f)
} else {
return nil, e
}
case "client":
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunconf.NewSAMClientForwarderFromConfig(s.FilePath, s.SamHost, s.SamPort, label)); e == nil {
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMClientForwarderFromConfig(s.config.FilePath, s.SamHost, s.SamPort, label)); e == nil {
log.Println("found client under", label)
s.handlerMux = s.handlerMux.Append(f)
} else {
return nil, e
}
case "udpserver":
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunconf.NewSAMSSUForwarderFromConfig(s.FilePath, s.SamHost, s.SamPort, label)); e == nil {
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMDGForwarderFromConfig(s.config.FilePath, s.SamHost, s.SamPort, label)); e == nil {
log.Println("found udpserver under", label)
s.handlerMux = s.handlerMux.Append(f)
} else {
return nil, e
}
case "udpclient":
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunconf.NewSAMSSUClientForwarderFromConfig(s.FilePath, s.SamHost, s.SamPort, label)); e == nil {
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMDGClientForwarderFromConfig(s.config.FilePath, s.SamHost, s.SamPort, label)); e == nil {
log.Println("found udpclient under", label)
s.handlerMux = s.handlerMux.Append(f)
} else {
return nil, e
}
case "eephttpd":
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewEepHttpdFromConfig(s.config.FilePath, s.SamHost, s.SamPort, label)); e == nil {
log.Println("found eephttpd under", label)
s.handlerMux = s.handlerMux.Append(f)
} else {
return nil, e
}
case "outproxy":
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewOutProxyFromConfig(s.config.FilePath, s.SamHost, s.SamPort, label)); e == nil {
log.Println("found outproxy under", label)
s.handlerMux = s.handlerMux.Append(f)
} else {
return nil, e
}
case "outproxyhttp":
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewHttpOutProxyFromConfig(s.config.FilePath, s.SamHost, s.SamPort, label)); e == nil {
log.Println("found outproxy under", label)
s.handlerMux = s.handlerMux.Append(f)
} else {
return nil, e
}
/*case "vpnserver":
if f, e := samtunnelhandler.NewTunnelHandler(samforwardervpnserver.NewSAMVPNForwarderFromConfig(s.FilePath, s.SamHost, s.SamPort, label)); e == nil {
if f, e := samtunnelhandler.NewTunnelHandler(samforwardervpnserver.NewSAMVPNForwarderFromConfig(s.config.FilePath, s.SamHost, s.SamPort, label)); e == nil {
log.Println("found vpnserver under", label)
s.handlerMux = s.handlerMux.Append(f)
} else {
return nil, e
}
case "vpnclient":
if f, e := samtunnelhandler.NewTunnelHandler(samforwardervpn.NewSAMVPNClientForwarderFromConfig(s.FilePath, s.SamHost, s.SamPort, label)); e == nil {
if f, e := samtunnelhandler.NewTunnelHandler(samforwardervpn.NewSAMVPNClientForwarderFromConfig(s.config.FilePath, s.SamHost, s.SamPort, label)); e == nil {
log.Println("found vpnclient under", label)
s.handlerMux = s.handlerMux.Append(f)
} else {
return nil, e
}*/
default:
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunconf.NewSAMForwarderFromConfig(s.FilePath, s.SamHost, s.SamPort, label)); e == nil {
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMForwarderFromConfig(s.config.FilePath, s.SamHost, s.SamPort, label)); e == nil {
log.Println("found server under", label)
s.handlerMux = s.handlerMux.Append(f)
} else {
@ -208,70 +230,91 @@ func NewSAMManagerFromOptions(opts ...func(*SAMManager) error) (*SAMManager, err
}
switch t {
case "http":
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunconf.NewSAMForwarderFromConf(s.config)); e == nil {
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMForwarderFromConf(s.config)); e == nil {
log.Println("found default http")
s.handlerMux = s.handlerMux.Append(f)
} else {
return nil, e
}
case "httpclient":
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunconf.NewSAMHTTPClientFromConf(s.config)); e == nil {
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMHTTPClientFromConf(s.config)); e == nil {
log.Println("found default httpclient")
s.handlerMux = s.handlerMux.Append(f)
} else {
return nil, e
}
case "browserclient":
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunconf.NewSAMBrowserClientFromConf(s.config)); e == nil {
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMBrowserClientFromConf(s.config)); e == nil {
log.Println("found default browserclient")
s.handlerMux = s.handlerMux.Append(f)
} else {
return nil, e
}
case "server":
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunconf.NewSAMForwarderFromConf(s.config)); e == nil {
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMForwarderFromConf(s.config)); e == nil {
log.Println("found default server")
s.handlerMux = s.handlerMux.Append(f)
} else {
return nil, e
}
case "client":
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunconf.NewSAMClientForwarderFromConf(s.config)); e == nil {
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMClientForwarderFromConf(s.config)); e == nil {
log.Println("found default client")
s.handlerMux = s.handlerMux.Append(f)
} else {
return nil, e
}
case "udpserver":
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunconf.NewSAMSSUForwarderFromConf(s.config)); e == nil {
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMDGForwarderFromConf(s.config)); e == nil {
log.Println("found default udpserver")
s.handlerMux = s.handlerMux.Append(f)
} else {
return nil, e
}
case "udpclient":
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunconf.NewSAMSSUClientForwarderFromConf(s.config)); e == nil {
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMDGClientForwarderFromConf(s.config)); e == nil {
log.Println("found default udpclient")
s.handlerMux = s.handlerMux.Append(f)
} else {
return nil, e
}
/*case "vpnserver":
if f, e := samtunnelhandler.NewTunnelHandler(samforwardervpnserver.NewSAMVPNForwarderFromConf(s.config)); e == nil {
log.Println("found default vpnserver")
case "eephttpd":
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewEepHttpdFromConf(s.config)); e == nil {
log.Println("found default udpclient")
s.handlerMux = s.handlerMux.Append(f)
} else {
return nil, e
}
case "vpnclient":
if f, e := samtunnelhandler.NewTunnelHandler(samforwardervpn.NewSAMVPNClientForwarderFromConf(s.config)); e == nil {
log.Println("found default vpnclient")
case "outproxy":
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewOutProxyFromConf(s.config)); e == nil {
log.Println("found default udpclient")
s.handlerMux = s.handlerMux.Append(f)
} else {
return nil, e
}*/
}
case "outproxyhttp":
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewHttpOutProxyFromConf(s.config)); e == nil {
log.Println("found default udpclient")
s.handlerMux = s.handlerMux.Append(f)
} else {
return nil, e
}
/*case "vpnserver":
if f, e := samtunnelhandler.NewTunnelHandler(samforwardervpnserver.NewSAMVPNForwarderFromConf(s.config)); e == nil {
log.Println("found default vpnserver")
s.handlerMux = s.handlerMux.Append(f)
} else {
return nil, e
}
case "vpnclient":
if f, e := samtunnelhandler.NewTunnelHandler(samforwardervpn.NewSAMVPNClientForwarderFromConf(s.config)); e == nil {
log.Println("found default vpnclient")
s.handlerMux = s.handlerMux.Append(f)
} else {
return nil, e
}*/
default:
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunconf.NewSAMClientForwarderFromConf(s.config)); e == nil {
if f, e := samtunnelhandler.NewTunnelHandler(i2ptunhelper.NewSAMClientForwarderFromConf(s.config)); e == nil {
log.Println("found default client")
s.handlerMux = s.handlerMux.Append(f)
} else {

View File

@ -1,4 +1,5 @@
// +build nostatic
// +build !static !cli
package sammanager

41
manager/noui.go Normal file
View File

@ -0,0 +1,41 @@
// +build cli
// +build !nostatic !static
package sammanager
import (
"log"
"os"
"os/signal"
"time"
)
func (s *SAMManager) RunUI() {
}
func (s *SAMManager) Serve() bool {
log.Println("Starting Tunnels()")
for _, element := range s.handlerMux.Tunnels() {
log.Println("Starting service tunnel", element.ID())
go element.Serve()
}
return Exit()
}
func Exit() bool {
Close := false
for !Close {
time.Sleep(1 * time.Second)
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
go func() {
for sig := range c {
log.Println(sig)
Close = true
}
}()
}
return false
}

View File

@ -1,4 +1,5 @@
// +build !nostatic
// +build static
// +build !nostatic !cli
package sammanager

450
options/options.go Normal file
View File

@ -0,0 +1,450 @@
package samoptions
import (
"fmt"
"strconv"
"github.com/eyedeekay/sam-forwarder/interface"
)
//Option is a SAMForwarder Option
type Option func(samtunnel.SAMTunnel) error
//SetFilePath sets the path to save the config file at.
func SetFilePath(s string) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
c.Config().FilePath = s
return nil
}
}
//SetType sets the type of the forwarder server
func SetType(s string) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
if s == "http" {
c.Config().Type = s
return nil
} else {
c.Config().Type = "server"
return nil
}
}
}
//SetSigType sets the type of the forwarder server
func SetSigType(s string) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
if s == "" {
c.Config().SigType = ""
} else if s == "DSA_SHA1" {
c.Config().SigType = "DSA_SHA1"
} else if s == "ECDSA_SHA256_P256" {
c.Config().SigType = "ECDSA_SHA256_P256"
} else if s == "ECDSA_SHA384_P384" {
c.Config().SigType = "ECDSA_SHA384_P384"
} else if s == "ECDSA_SHA512_P521" {
c.Config().SigType = "ECDSA_SHA512_P521"
} else if s == "EdDSA_SHA512_Ed25519" {
c.Config().SigType = "EdDSA_SHA512_Ed25519"
} else {
c.Config().SigType = "EdDSA_SHA512_Ed25519"
}
return nil
}
}
//SetSaveFile tells the router to save the tunnel's keys long-term
func SetSaveFile(b bool) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
c.Config().SaveFile = b
return nil
}
}
//SetHost sets the host of the service to forward
func SetHost(s string) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
c.Config().TargetHost = s
return nil
}
}
//SetPort sets the port of the service to forward
func SetPort(s string) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
port, err := strconv.Atoi(s)
if err != nil {
return fmt.Errorf("Invalid TCP Server Target Port %s; non-number ", s)
}
if port < 65536 && port > -1 {
c.Config().TargetPort = s
return nil
}
return fmt.Errorf("Invalid port")
}
}
//SetSAMHost sets the host of the SAMForwarder's SAM bridge
func SetSAMHost(s string) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
c.Config().SamHost = s
return nil
}
}
//SetSAMPort sets the port of the SAMForwarder's SAM bridge using a string
func SetSAMPort(s string) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
port, err := strconv.Atoi(s)
if err != nil {
return fmt.Errorf("Invalid SAM Port %s; non-number", s)
}
if port < 65536 && port > -1 {
c.Config().SamPort = s
return nil
}
return fmt.Errorf("Invalid port")
}
}
//SetName sets the host of the SAMForwarder's SAM bridge
func SetName(s string) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
c.Config().TunName = s
return nil
}
}
//SetInLength sets the number of hops inbound
func SetInLength(u int) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
if u < 7 && u >= 0 {
c.Config().InLength = u
return nil
}
return fmt.Errorf("Invalid inbound tunnel length")
}
}
//SetOutLength sets the number of hops outbound
func SetOutLength(u int) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
if u < 7 && u >= 0 {
c.Config().OutLength = u
return nil
}
return fmt.Errorf("Invalid outbound tunnel length")
}
}
//SetInVariance sets the variance of a number of hops inbound
func SetInVariance(i int) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
if i < 7 && i > -7 {
c.Config().InVariance = i
return nil
}
return fmt.Errorf("Invalid inbound tunnel length")
}
}
//SetOutVariance sets the variance of a number of hops outbound
func SetOutVariance(i int) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
if i < 7 && i > -7 {
c.Config().OutVariance = i
return nil
}
return fmt.Errorf("Invalid outbound tunnel variance")
}
}
//SetInQuantity sets the inbound tunnel quantity
func SetInQuantity(u int) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
if u <= 16 && u > 0 {
c.Config().InQuantity = u
return nil
}
return fmt.Errorf("Invalid inbound tunnel quantity")
}
}
//SetOutQuantity sets the outbound tunnel quantity
func SetOutQuantity(u int) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
if u <= 16 && u > 0 {
c.Config().OutQuantity = u
return nil
}
return fmt.Errorf("Invalid outbound tunnel quantity")
}
}
//SetInBackups sets the inbound tunnel backups
func SetInBackups(u int) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
if u < 6 && u >= 0 {
c.Config().InBackupQuantity = u
return nil
}
return fmt.Errorf("Invalid inbound tunnel backup quantity")
}
}
//SetOutBackups sets the inbound tunnel backups
func SetOutBackups(u int) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
if u < 6 && u >= 0 {
c.Config().OutBackupQuantity = u
return nil
}
return fmt.Errorf("Invalid outbound tunnel backup quantity")
}
}
//SetEncrypt tells the router to use an encrypted leaseset
func SetEncrypt(b bool) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
if b {
c.Config().EncryptLeaseSet = true
return nil
}
c.Config().EncryptLeaseSet = false
return nil
}
}
//SetLeaseSetKey sets the host of the SAMForwarder's SAM bridge
func SetLeaseSetKey(s string) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
c.Config().LeaseSetKey = s
return nil
}
}
//SetLeaseSetPrivateKey sets the host of the SAMForwarder's SAM bridge
func SetLeaseSetPrivateKey(s string) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
c.Config().LeaseSetPrivateKey = s
return nil
}
}
//SetLeaseSetPrivateSigningKey sets the host of the SAMForwarder's SAM bridge
func SetLeaseSetPrivateSigningKey(s string) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
c.Config().LeaseSetPrivateSigningKey = s
return nil
}
}
//SetMessageReliability sets the host of the SAMForwarder's SAM bridge
func SetMessageReliability(s string) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
c.Config().MessageReliability = s
return nil
}
}
//SetAllowZeroIn tells the tunnel to accept zero-hop peers
func SetAllowZeroIn(b bool) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
if b {
c.Config().InAllowZeroHop = true
return nil
}
c.Config().InAllowZeroHop = false
return nil
}
}
//SetAllowZeroOut tells the tunnel to accept zero-hop peers
func SetAllowZeroOut(b bool) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
if b {
c.Config().OutAllowZeroHop = true
return nil
}
c.Config().OutAllowZeroHop = false
return nil
}
}
//SetCompress tells clients to use compression
func SetCompress(b bool) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
if b {
c.Config().UseCompression = true
return nil
}
c.Config().UseCompression = false
return nil
}
}
//SetFastRecieve tells clients to use compression
func SetFastRecieve(b bool) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
if b {
c.Config().FastRecieve = true
return nil
}
c.Config().FastRecieve = false
return nil
}
}
//SetReduceIdle tells the connection to reduce it's tunnels during extended idle time.
func SetReduceIdle(b bool) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
if b {
c.Config().ReduceIdle = true
return nil
}
c.Config().ReduceIdle = false
return nil
}
}
//SetReduceIdleTime sets the time to wait before reducing tunnels to idle levels
func SetReduceIdleTime(u int) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
c.Config().ReduceIdleTime = 300000
if u >= 6 {
c.Config().ReduceIdleTime = (u * 60) * 1000
return nil
}
return fmt.Errorf("Invalid reduce idle timeout(Measured in minutes) %v", u)
}
}
//SetReduceIdleTimeMs sets the time to wait before reducing tunnels to idle levels in milliseconds
func SetReduceIdleTimeMs(u int) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
c.Config().ReduceIdleTime = 300000
if u >= 300000 {
c.Config().ReduceIdleTime = u
return nil
}
return fmt.Errorf("Invalid reduce idle timeout(Measured in milliseconds) %v", u)
}
}
//SetReduceIdleQuantity sets minimum number of tunnels to reduce to during idle time
func SetReduceIdleQuantity(u int) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
if u < 5 {
c.Config().ReduceIdleQuantity = u
return nil
}
return fmt.Errorf("Invalid reduce tunnel quantity")
}
}
//SetCloseIdle tells the connection to close it's tunnels during extended idle time.
func SetCloseIdle(b bool) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
if b {
c.Config().CloseIdle = true
return nil
}
c.Config().CloseIdle = false
return nil
}
}
//SetCloseIdleTime sets the time to wait before closing tunnels to idle levels
func SetCloseIdleTime(u int) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
c.Config().CloseIdleTime = 300000
if u >= 6 {
c.Config().CloseIdleTime = (u * 60) * 1000
return nil
}
return fmt.Errorf("Invalid close idle timeout(Measured in minutes) %v", u)
}
}
//SetCloseIdleTimeMs sets the time to wait before closing tunnels to idle levels in milliseconds
func SetCloseIdleTimeMs(u int) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
c.Config().CloseIdleTime = 300000
if u >= 300000 {
c.Config().CloseIdleTime = u
return nil
}
return fmt.Errorf("Invalid close idle timeout(Measured in milliseconds) %v", u)
}
}
//SetAccessListType tells the system to treat the AccessList as a allowlist
func SetAccessListType(s string) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
if s == "allowlist" {
c.Config().AccessListType = "allowlist"
return nil
} else if s == "blocklist" {
c.Config().AccessListType = "blocklist"
return nil
} else if s == "none" {
c.Config().AccessListType = ""
return nil
} else if s == "" {
c.Config().AccessListType = ""
return nil
}
return fmt.Errorf("Invalid Access list type(allowlist, blocklist, none)")
}
}
//SetAccessList tells the system to treat the AccessList as a allowlist
func SetAccessList(s []string) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
if len(s) > 0 {
for _, a := range s {
c.Config().AccessList = append(c.Config().AccessList, a)
}
return nil
}
return nil
}
}
//SetTargetForPort sets the port of the SAMForwarder's SAM bridge using a string
/*func SetTargetForPort443(s string) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
port, err := strconv.Atoi(s)
if err != nil {
return fmt.Errorf("Invalid Target Port %s; non-number ", s)
}
if port < 65536 && port > -1 {
c.Config().TargetForPort443 = s
return nil
}
return fmt.Errorf("Invalid port")
}
}
*/
//SetKeyFile sets
func SetKeyFile(s string) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
c.Config().KeyFilePath = s
return nil
}
}
func SetPassword(s string) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
c.Config().KeyFilePath = s
return nil
}
}
func SetDestination(s string) func(samtunnel.SAMTunnel) error {
return func(c samtunnel.SAMTunnel) error {
c.Config().ClientDest = s
return nil
}
}

View File

@ -15,7 +15,6 @@ import (
"github.com/eyedeekay/sam-forwarder/config"
"github.com/eyedeekay/sam-forwarder/hashhash"
"github.com/eyedeekay/sam-forwarder/manager"
//"github.com/eyedeekay/samcatd-web"
)
type flagOpts []string
@ -80,6 +79,8 @@ var (
"custom CSS for web interface")
webJS = flag.String("js", "js/scripts.js",
"custom JS for web interface")
webDir = flag.String("wwwdir", "./www",
"Default www directory to serve if starting eephttpd")
leaseSetKey = flag.String("k", "none",
"key for encrypted leaseset")
leaseSetPrivateKey = flag.String("pk", "none",
@ -109,7 +110,7 @@ var (
tunName = flag.String("n", "forwarder",
"Tunnel name, this must be unique but can be anything.")
accessListType = flag.String("a", "none",
"Type of access list to use, can be \"whitelist\" \"blacklist\" or \"none\".")
"Type of access list to use, can be \"allowlist\" \"blocklist\" or \"none\".")
inLength = flag.Int("il", 3,
"Set inbound tunnel length(0 to 7)")
outLength = flag.Int("ol", 3,
@ -191,6 +192,7 @@ func lbMain(ctx context.Context) {
}
config.TargetHost = config.GetHost(*targetHost, "127.0.0.1")
config.TargetPort = config.GetPort(*targetPort, "8081")
config.FilePath = *iniFile
config.SaveFile = config.GetSaveFile(*saveFile, true)
config.SaveDirectory = config.GetDir(*targetDir, "../")
config.SamHost = config.GetSAMHost(*samHost, "127.0.0.1")
@ -218,12 +220,13 @@ func lbMain(ctx context.Context) {
config.AccessListType = config.GetAccessListType(*accessListType, "none")
config.CloseIdle = config.GetCloseOnIdle(*closeIdle, false)
config.CloseIdleTime = config.GetCloseIdleTime(*closeIdleTime, 600000)
config.Type = config.GetType(*client, *udpMode, *injectHeaders, "server")
config.Type = config.GetTypes(*client, *udpMode, *injectHeaders, "server")
config.TargetForPort443 = config.GetPort443(*targetPort443, "")
config.KeyFilePath = config.GetKeyFile(*encryptKeyFiles, "")
config.ClientDest = config.GetClientDest(*targetDest, "", "")
config.UserName = config.GetUserName(*webUser, "samcatd")
config.Password = config.GetPassword(*webPass, "")
config.ServeDirectory = config.GetWWWDir(*webDir, "./www")
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)

View File

@ -111,7 +111,7 @@ func echoclient() {
}
func serveudp() {
ssuforwarder, err = samforwarderudp.NewSAMSSUForwarderFromOptions(
ssuforwarder, err = samforwarderudp.NewSAMDGForwarderFromOptions(
samforwarderudp.SetHost("127.0.0.1"),
samforwarderudp.SetPort(UDPServerPort),
samforwarderudp.SetSAMHost("127.0.0.1"),
@ -130,7 +130,7 @@ func serveudp() {
}
func clientudp() {
ssuforwarderclient, err = samforwarderudp.NewSAMSSUClientForwarderFromOptions(
ssuforwarderclient, err = samforwarderudp.NewSAMDGClientForwarderFromOptions(
samforwarderudp.SetClientHost("127.0.0.1"),
samforwarderudp.SetClientPort(UDPClientPort),
samforwarderudp.SetClientSAMHost("127.0.0.1"),

View File

@ -1,413 +0,0 @@
package samforwarder
import (
"fmt"
"strconv"
)
//ClientOption is a SAMClientForwarder Option
type ClientOption func(*SAMClientForwarder) error
//SetClientFilePath sets the host of the SAMClientForwarder's SAM bridge
func SetClientFilePath(s string) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
c.FilePath = s
return nil
}
}
//SetClientSaveFile tells the router to save the tunnel keys long-term
func SetClientSaveFile(b bool) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
c.save = b
return nil
}
}
//SetClientHost sets the host of the SAMClientForwarder's SAM bridge
func SetClientHost(s string) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
c.TargetHost = s
return nil
}
}
//SetClientDestination sets the destination to forwarder SAMClientForwarder's to
func SetClientDestination(s string) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
c.dest = s
return nil
}
}
//SetClientPort sets the port of the SAMClientForwarder's SAM bridge using a string
func SetClientPort(s string) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
port, err := strconv.Atoi(s)
if err != nil {
return fmt.Errorf("Invalid TCP Client Target Port %s; non-number ", s)
}
if port < 65536 && port > -1 {
c.TargetPort = s
return nil
}
return fmt.Errorf("Invalid port")
}
}
//SetClientSAMHost sets the host of the SAMClientForwarder's SAM bridge
func SetClientSAMHost(s string) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
c.SamHost = s
return nil
}
}
//SetClientSAMPort sets the port of the SAMClientForwarder's SAM bridge using a string
func SetClientSAMPort(s string) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
port, err := strconv.Atoi(s)
if err != nil {
return fmt.Errorf("Invalid SAM Port %s; non-number", s)
}
if port < 65536 && port > -1 {
c.SamPort = s
return nil
}
return fmt.Errorf("Invalid port")
}
}
//SetClientName sets the host of the SAMClientForwarder's SAM bridge
func SetClientName(s string) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
c.TunName = s
return nil
}
}
//SetSigType sets the type of the forwarder server
func SetClientSigType(s string) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
if s == "" {
c.sigType = ""
} else if s == "DSA_SHA1" {
c.sigType = "DSA_SHA1"
} else if s == "ECDSA_SHA256_P256" {
c.sigType = "ECDSA_SHA256_P256"
} else if s == "ECDSA_SHA384_P384" {
c.sigType = "ECDSA_SHA384_P384"
} else if s == "ECDSA_SHA512_P521" {
c.sigType = "ECDSA_SHA512_P521"
} else if s == "EdDSA_SHA512_Ed25519" {
c.sigType = "EdDSA_SHA512_Ed25519"
} else {
c.sigType = "EdDSA_SHA512_Ed25519"
}
return nil
}
}
//SetClientInLength sets the number of hops inbound
func SetClientInLength(u int) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
if u < 7 && u >= 0 {
c.inLength = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid inbound tunnel length")
}
}
//SetClientOutLength sets the number of hops outbound
func SetClientOutLength(u int) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
if u < 7 && u >= 0 {
c.outLength = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid outbound tunnel length")
}
}
//SetClientInVariance sets the variance of a number of hops inbound
func SetClientInVariance(i int) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
if i < 7 && i > -7 {
c.inVariance = strconv.Itoa(i)
return nil
}
return fmt.Errorf("Invalid inbound tunnel length")
}
}
//SetClientOutVariance sets the variance of a number of hops outbound
func SetClientOutVariance(i int) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
if i < 7 && i > -7 {
c.outVariance = strconv.Itoa(i)
return nil
}
return fmt.Errorf("Invalid outbound tunnel variance")
}
}
//SetClientInQuantity sets the inbound tunnel quantity
func SetClientInQuantity(u int) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
if u <= 16 && u > 0 {
c.inQuantity = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid inbound tunnel quantity")
}
}
//SetClientOutQuantity sets the outbound tunnel quantity
func SetClientOutQuantity(u int) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
if u <= 16 && u > 0 {
c.outQuantity = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid outbound tunnel quantity")
}
}
//SetClientInBackups sets the inbound tunnel backups
func SetClientInBackups(u int) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
if u < 6 && u >= 0 {
c.inBackupQuantity = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid inbound tunnel backup quantity")
}
}
//SetClientOutBackups sets the inbound tunnel backups
func SetClientOutBackups(u int) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
if u < 6 && u >= 0 {
c.outBackupQuantity = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid outbound tunnel backup quantity")
}
}
//SetClientEncrypt tells the router to use an encrypted leaseset
func SetClientEncrypt(b bool) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
if b {
c.encryptLeaseSet = "true"
return nil
}
c.encryptLeaseSet = "false"
return nil
}
}
//SetClientLeaseSetKey sets
func SetClientLeaseSetKey(s string) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
c.leaseSetKey = s
return nil
}
}
//SetClientLeaseSetPrivateKey sets
func SetClientLeaseSetPrivateKey(s string) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
c.leaseSetPrivateKey = s
return nil
}
}
//SetClientLeaseSetPrivateSigningKey sets
func SetClientLeaseSetPrivateSigningKey(s string) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
c.leaseSetPrivateSigningKey = s
return nil
}
}
//SetClientMessageReliability sets
func SetClientMessageReliability(s string) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
c.messageReliability = s
return nil
}
}
//SetClientAllowZeroIn tells the tunnel to accept zero-hop peers
func SetClientAllowZeroIn(b bool) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
if b {
c.inAllowZeroHop = "true"
return nil
}
c.inAllowZeroHop = "false"
return nil
}
}
//SetClientAllowZeroOut tells the tunnel to accept zero-hop peers
func SetClientAllowZeroOut(b bool) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
if b {
c.outAllowZeroHop = "true"
return nil
}
c.outAllowZeroHop = "false"
return nil
}
}
//SetClientFastRecieve tells clients use the i2cp.fastRecieve option
func SetClientFastRecieve(b bool) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
if b {
c.fastRecieve = "true"
return nil
}
c.fastRecieve = "false"
return nil
}
}
//SetClientCompress tells clients to use compression
func SetClientCompress(b bool) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
if b {
c.useCompression = "true"
return nil
}
c.useCompression = "false"
return nil
}
}
//SetClientReduceIdle tells the connection to reduce it's tunnels during extended idle time.
func SetClientReduceIdle(b bool) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
if b {
c.reduceIdle = "true"
return nil
}
c.reduceIdle = "false"
return nil
}
}
//SetClientReduceIdleTime sets the time to wait before reducing tunnels to idle levels
func SetClientReduceIdleTime(u int) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
c.reduceIdleTime = strconv.Itoa(300000)
if u >= 6 {
c.reduceIdleTime = strconv.Itoa((u * 60) * 1000)
return nil
}
return fmt.Errorf("Invalid reduce idle timeout(Measured in minutes) %v", u)
}
}
//SetClientReduceIdleTimeMs sets the time to wait before reducing tunnels to idle levels in milliseconds
func SetClientReduceIdleTimeMs(u int) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
c.reduceIdleTime = strconv.Itoa(300000)
if u >= 300000 {
c.reduceIdleTime = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid reduce idle timeout(Measured in milliseconds) %v", u)
}
}
//SetClientReduceIdleQuantity sets minimum number of tunnels to reduce to during idle time
func SetClientReduceIdleQuantity(u int) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
if u < 5 {
c.reduceIdleQuantity = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid reduce tunnel quantity")
}
}
//SetClientCloseIdle tells the connection to close it's tunnels during extended idle time.
func SetClientCloseIdle(b bool) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
if b {
c.closeIdle = "true"
return nil
}
c.closeIdle = "false"
return nil
}
}
//SetClientCloseIdleTime sets the time to wait before closing tunnels to idle levels
func SetClientCloseIdleTime(u int) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
c.closeIdleTime = "300000"
if u >= 6 {
c.closeIdleTime = strconv.Itoa((u * 60) * 1000)
return nil
}
return fmt.Errorf("Invalid close idle timeout(Measured in minutes) %v", u)
}
}
//SetClientCloseIdleTimeMs sets the time to wait before closing tunnels to idle levels in milliseconds
func SetClientCloseIdleTimeMs(u int) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
c.closeIdleTime = "300000"
if u >= 300000 {
c.closeIdleTime = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid close idle timeout(Measured in milliseconds) %v", u)
}
}
//SetClientAccessListType tells the system to treat the accessList as a whitelist
func SetClientAccessListType(s string) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
if s == "whitelist" {
c.accessListType = "whitelist"
return nil
} else if s == "blacklist" {
c.accessListType = "blacklist"
return nil
} else if s == "none" {
c.accessListType = ""
return nil
} else if s == "" {
c.accessListType = ""
return nil
}
return fmt.Errorf("Invalid Access list type(whitelist, blacklist, none)")
}
}
//SetClientAccessList tells the system to treat the accessList as a whitelist
func SetClientAccessList(s []string) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
if len(s) > 0 {
for _, a := range s {
c.accessList = append(c.accessList, a)
}
return nil
}
return nil
}
}
//SetKeyFile sets
func SetClientPassword(s string) func(*SAMClientForwarder) error {
return func(c *SAMClientForwarder) error {
c.passfile = s
return nil
}
}

View File

@ -11,76 +11,46 @@ import (
)
import (
"github.com/eyedeekay/sam-forwarder/config"
"github.com/eyedeekay/sam-forwarder/hashhash"
"github.com/eyedeekay/sam-forwarder/i2pkeys"
"github.com/eyedeekay/sam-forwarder/interface"
"github.com/eyedeekay/sam-forwarder/options"
"github.com/eyedeekay/sam3"
"github.com/eyedeekay/sam3/i2pkeys"
)
// SAMClientForwarder is a tcp proxy that automatically forwards ports to i2p
type SAMClientForwarder struct {
SamHost string
SamPort string
TunName string
Type string
TargetHost string
TargetPort string
samConn *sam3.SAM
SamKeys i2pkeys.I2PKeys
Hasher *hashhash.Hasher
connectStream *sam3.StreamSession
dest string
addr i2pkeys.I2PAddr
publishConnection net.Listener
Bytes map[string]int
ByteLimit int
FilePath string
file io.ReadWriter
save bool
up bool
file io.ReadWriter
up bool
// samcatd options
passfile string
sigType string
// config
Conf *i2ptunconf.Conf
}
// I2CP options
encryptLeaseSet string
leaseSetKey string
leaseSetPrivateKey string
leaseSetPrivateSigningKey string
LeaseSetKeys *i2pkeys.I2PKeys
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
//Streaming Library options
accessListType string
accessList []string
func (f *SAMClientForwarder) Config() *i2ptunconf.Conf {
if f.Conf == nil {
f.Conf = i2ptunconf.NewI2PBlankTunConf()
}
return f.Conf
}
func (f *SAMClientForwarder) GetType() string {
return f.Type
return f.Config().Type
}
func (f *SAMClientForwarder) ID() string {
return f.TunName
return f.Config().TunName
}
func (f *SAMClientForwarder) Keys() i2pkeys.I2PKeys {
@ -88,32 +58,7 @@ func (f *SAMClientForwarder) Keys() i2pkeys.I2PKeys {
}
func (f *SAMClientForwarder) print() []string {
lsk, lspk, lspsk := f.leasesetsettings()
return []string{
//f.targetForPort443(),
"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,
"inbound.allowZeroHop=" + f.inAllowZeroHop,
"outbound.allowZeroHop=" + f.outAllowZeroHop,
"i2cp.fastRecieve=" + f.fastRecieve,
"i2cp.gzip=" + f.useCompression,
"i2cp.reduceOnIdle=" + f.reduceIdle,
"i2cp.reduceIdleTime=" + f.reduceIdleTime,
"i2cp.reduceQuantity=" + f.reduceIdleQuantity,
"i2cp.closeOnIdle=" + f.closeIdle,
"i2cp.closeIdleTime=" + f.closeIdleTime,
"i2cp.messageReliability=" + f.messageReliability,
"i2cp.encryptLeaseSet=" + f.encryptLeaseSet,
lsk, lspk, lspsk,
f.accesslisttype(),
f.accesslist(),
}
return f.Config().PrintSlice()
}
func (f *SAMClientForwarder) Props() map[string]string {
@ -137,12 +82,12 @@ func (f *SAMClientForwarder) Cleanup() {
func (f *SAMClientForwarder) Print() string {
var r string
r += "name=" + f.TunName + "\n"
r += "type=" + f.Type + "\n"
r += "name=" + f.Config().TunName + "\n"
r += "type=" + f.Config().Type + "\n"
r += "base32=" + f.Base32() + "\n"
r += "base64=" + f.Base64() + "\n"
r += "dest=" + f.dest + "\n"
r += "ntcpclient\n"
r += "dest=" + f.Config().ClientDest + "\n"
//r += "ntcpclient\n"
for _, s := range f.print() {
r += s + "\n"
}
@ -164,20 +109,20 @@ func (f *SAMClientForwarder) Search(search string) string {
}
func (f *SAMClientForwarder) accesslisttype() string {
if f.accessListType == "whitelist" {
if f.Config().AccessListType == "allowlist" {
return "i2cp.enableAccessList=true"
} else if f.accessListType == "blacklist" {
} else if f.Config().AccessListType == "blocklist" {
return "i2cp.enableBlackList=true"
} else if f.accessListType == "none" {
} else if f.Config().AccessListType == "none" {
return ""
}
return ""
}
func (f *SAMClientForwarder) accesslist() string {
if f.accessListType != "" && len(f.accessList) > 0 {
if f.Config().AccessListType != "" && len(f.Config().AccessList) > 0 {
r := ""
for _, s := range f.accessList {
for _, s := range f.Config().AccessList {
r += s + ","
}
return "i2cp.accessList=" + strings.TrimSuffix(r, ",")
@ -187,21 +132,21 @@ func (f *SAMClientForwarder) accesslist() string {
func (f *SAMClientForwarder) leasesetsettings() (string, string, string) {
var r, s, t string
if f.leaseSetKey != "" {
r = "i2cp.leaseSetKey=" + f.leaseSetKey
if f.Config().LeaseSetKey != "" {
r = "i2cp.leaseSetKey=" + f.Config().LeaseSetKey
}
if f.leaseSetPrivateKey != "" {
s = "i2cp.leaseSetPrivateKey=" + f.leaseSetPrivateKey
if f.Config().LeaseSetPrivateKey != "" {
s = "i2cp.leaseSetPrivateKey=" + f.Config().LeaseSetPrivateKey
}
if f.leaseSetPrivateSigningKey != "" {
t = "i2cp.leaseSetPrivateSigningKey=" + f.leaseSetPrivateSigningKey
if f.Config().LeaseSetPrivateSigningKey != "" {
t = "i2cp.leaseSetPrivateSigningKey=" + f.Config().LeaseSetPrivateSigningKey
}
return r, s, t
}
// Target returns the host:port of the local service you want to forward to i2p
func (f *SAMClientForwarder) Target() string {
return f.TargetHost + ":" + f.TargetPort
return f.Config().TargetHost + ":" + f.Config().TargetPort
}
// Destination returns the destination of the i2p service you want to forward locally
@ -210,7 +155,7 @@ func (f *SAMClientForwarder) Destination() string {
}
func (f *SAMClientForwarder) sam() string {
return f.SamHost + ":" + f.SamPort
return f.Config().SamHost + ":" + f.Config().SamPort
}
//Base32 returns the base32 address of the local destination
@ -250,10 +195,10 @@ func (f *SAMClientForwarder) forward(conn net.Conn) {
//Serve starts the SAM connection and and forwards the local host:port to i2p
func (f *SAMClientForwarder) Serve() error {
if f.addr, err = f.samConn.Lookup(f.dest); err != nil {
if f.addr, err = f.samConn.Lookup(f.Config().ClientDest); err != nil {
return err
}
if f.connectStream, err = f.samConn.NewStreamSession(f.TunName, f.SamKeys, f.print()); err != nil {
if f.connectStream, err = f.samConn.NewStreamSession(f.Config().TunName, f.SamKeys, f.print()); err != nil {
log.Println("Stream Creation error:", err.Error())
return err
}
@ -285,25 +230,25 @@ func (f *SAMClientForwarder) Close() error {
}
func (s *SAMClientForwarder) Load() (samtunnel.SAMTunnel, error) {
if s.publishConnection, err = net.Listen("tcp", s.TargetHost+":"+s.TargetPort); err != nil {
if s.publishConnection, err = net.Listen("tcp", s.Config().TargetHost+":"+s.Config().TargetPort); err != nil {
return nil, err
}
if s.samConn, err = sam3.NewSAM(s.sam()); err != nil {
return nil, err
}
log.Println("SAM Bridge connection established.")
if s.save {
if s.Config().SaveFile {
log.Println("Saving i2p keys")
}
if s.SamKeys, err = sfi2pkeys.Load(s.FilePath, s.TunName, s.passfile, s.samConn, s.save); err != nil {
if s.SamKeys, err = sfi2pkeys.Load(s.Config().FilePath, s.Config().TunName, s.Config().KeyFilePath, s.samConn, s.Config().SaveFile); err != nil {
return nil, err
}
log.Println("Destination keys generated, tunnel name:", s.TunName)
if s.save {
if err := sfi2pkeys.Save(s.FilePath, s.TunName, s.passfile, s.SamKeys); err != nil {
log.Println("Destination keys generated, tunnel name:", s.Config().TunName)
if s.Config().SaveFile {
if err := sfi2pkeys.Save(s.Config().FilePath, s.Config().TunName, s.Config().KeyFilePath, s.SamKeys); err != nil {
return nil, err
}
log.Println("Saved tunnel keys for", s.TunName)
log.Println("Saved tunnel keys for", s.Conf.TunName, "in", s.Conf.FilePath)
}
s.Hasher, err = hashhash.NewHasher(len(strings.Replace(s.Base32(), ".b32.i2p", "", 1)))
if err != nil {
@ -314,46 +259,15 @@ func (s *SAMClientForwarder) Load() (samtunnel.SAMTunnel, error) {
}
//NewSAMClientForwarder makes a new SAM forwarder with default options, accepts host:port arguments
func NewSAMClientForwarder(host, port string) (*SAMClientForwarder, error) {
return NewSAMClientForwarderFromOptions(SetClientHost(host), SetClientPort(port))
func NewSAMClientForwarder(host, port string) (samtunnel.SAMTunnel, error) {
return NewSAMClientForwarderFromOptions(samoptions.SetHost(host), samoptions.SetPort(port))
}
//NewSAMClientForwarderFromOptions makes a new SAM forwarder with default options, accepts host:port arguments
func NewSAMClientForwarderFromOptions(opts ...func(*SAMClientForwarder) error) (*SAMClientForwarder, error) {
func NewSAMClientForwarderFromOptions(opts ...func(samtunnel.SAMTunnel) error) (*SAMClientForwarder, error) {
var s SAMClientForwarder
s.SamHost = "127.0.0.1"
s.SamPort = "7656"
s.FilePath = ""
s.save = false
s.TargetHost = "127.0.0.1"
s.TargetPort = "0"
s.TunName = "samForwarder"
s.inLength = "3"
s.outLength = "3"
s.inQuantity = "2"
s.outQuantity = "2"
s.inVariance = "1"
s.outVariance = "1"
s.inBackupQuantity = "3"
s.outBackupQuantity = "3"
s.inAllowZeroHop = "false"
s.outAllowZeroHop = "false"
s.encryptLeaseSet = "false"
s.leaseSetKey = ""
s.leaseSetPrivateKey = ""
s.leaseSetPrivateSigningKey = ""
s.fastRecieve = "false"
s.useCompression = "true"
s.reduceIdle = "false"
s.reduceIdleTime = "300000"
s.reduceIdleQuantity = "4"
s.closeIdle = "false"
s.closeIdleTime = "300000"
s.dest = "none"
s.Type = "client"
s.messageReliability = "none"
s.passfile = ""
s.dest = "i2p-projekt.i2p"
s.Conf = i2ptunconf.NewI2PBlankTunConf()
s.Conf.Type = "tcpclient"
for _, o := range opts {
if err := o(&s); err != nil {
return nil, err

View File

@ -1,434 +1,9 @@
package samforwarder
import (
"fmt"
"strconv"
)
//Option is a SAMForwarder Option
type Option func(*SAMForwarder) error
//SetFilePath sets the path to save the config file at.
func SetFilePath(s string) func(*SAMForwarder) error {
//SetByteLimit sets the number of hops inbound
func SetByteLimit(u int64) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
c.FilePath = s
return nil
}
}
//SetType sets the type of the forwarder server
func SetType(s string) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
if s == "http" {
c.Type = s
return nil
} else {
c.Type = "server"
return nil
}
}
}
//SetSigType sets the type of the forwarder server
func SetSigType(s string) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
if s == "" {
c.sigType = ""
} else if s == "DSA_SHA1" {
c.sigType = "DSA_SHA1"
} else if s == "ECDSA_SHA256_P256" {
c.sigType = "ECDSA_SHA256_P256"
} else if s == "ECDSA_SHA384_P384" {
c.sigType = "ECDSA_SHA384_P384"
} else if s == "ECDSA_SHA512_P521" {
c.sigType = "ECDSA_SHA512_P521"
} else if s == "EdDSA_SHA512_Ed25519" {
c.sigType = "EdDSA_SHA512_Ed25519"
} else {
c.sigType = "EdDSA_SHA512_Ed25519"
}
return nil
}
}
//SetSaveFile tells the router to save the tunnel's keys long-term
func SetSaveFile(b bool) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
c.save = b
return nil
}
}
//SetHost sets the host of the service to forward
func SetHost(s string) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
c.TargetHost = s
return nil
}
}
//SetPort sets the port of the service to forward
func SetPort(s string) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
port, err := strconv.Atoi(s)
if err != nil {
return fmt.Errorf("Invalid TCP Server Target Port %s; non-number ", s)
}
if port < 65536 && port > -1 {
c.TargetPort = s
return nil
}
return fmt.Errorf("Invalid port")
}
}
//SetSAMHost sets the host of the SAMForwarder's SAM bridge
func SetSAMHost(s string) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
c.SamHost = s
return nil
}
}
//SetSAMPort sets the port of the SAMForwarder's SAM bridge using a string
func SetSAMPort(s string) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
port, err := strconv.Atoi(s)
if err != nil {
return fmt.Errorf("Invalid SAM Port %s; non-number", s)
}
if port < 65536 && port > -1 {
c.SamPort = s
return nil
}
return fmt.Errorf("Invalid port")
}
}
//SetName sets the host of the SAMForwarder's SAM bridge
func SetName(s string) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
c.TunName = s
return nil
}
}
//SetInLength sets the number of hops inbound
func SetInLength(u int) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
if u < 7 && u >= 0 {
c.inLength = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid inbound tunnel length")
}
}
//SetOutLength sets the number of hops outbound
func SetOutLength(u int) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
if u < 7 && u >= 0 {
c.outLength = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid outbound tunnel length")
}
}
//SetInVariance sets the variance of a number of hops inbound
func SetInVariance(i int) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
if i < 7 && i > -7 {
c.inVariance = strconv.Itoa(i)
return nil
}
return fmt.Errorf("Invalid inbound tunnel length")
}
}
//SetOutVariance sets the variance of a number of hops outbound
func SetOutVariance(i int) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
if i < 7 && i > -7 {
c.outVariance = strconv.Itoa(i)
return nil
}
return fmt.Errorf("Invalid outbound tunnel variance")
}
}
//SetInQuantity sets the inbound tunnel quantity
func SetInQuantity(u int) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
if u <= 16 && u > 0 {
c.inQuantity = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid inbound tunnel quantity")
}
}
//SetOutQuantity sets the outbound tunnel quantity
func SetOutQuantity(u int) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
if u <= 16 && u > 0 {
c.outQuantity = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid outbound tunnel quantity")
}
}
//SetInBackups sets the inbound tunnel backups
func SetInBackups(u int) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
if u < 6 && u >= 0 {
c.inBackupQuantity = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid inbound tunnel backup quantity")
}
}
//SetOutBackups sets the inbound tunnel backups
func SetOutBackups(u int) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
if u < 6 && u >= 0 {
c.outBackupQuantity = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid outbound tunnel backup quantity")
}
}
//SetEncrypt tells the router to use an encrypted leaseset
func SetEncrypt(b bool) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
if b {
c.encryptLeaseSet = "true"
return nil
}
c.encryptLeaseSet = "false"
return nil
}
}
//SetLeaseSetKey sets the host of the SAMForwarder's SAM bridge
func SetLeaseSetKey(s string) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
c.leaseSetKey = s
return nil
}
}
//SetLeaseSetPrivateKey sets the host of the SAMForwarder's SAM bridge
func SetLeaseSetPrivateKey(s string) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
c.leaseSetPrivateKey = s
return nil
}
}
//SetLeaseSetPrivateSigningKey sets the host of the SAMForwarder's SAM bridge
func SetLeaseSetPrivateSigningKey(s string) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
c.leaseSetPrivateSigningKey = s
return nil
}
}
//SetMessageReliability sets the host of the SAMForwarder's SAM bridge
func SetMessageReliability(s string) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
c.messageReliability = s
return nil
}
}
//SetAllowZeroIn tells the tunnel to accept zero-hop peers
func SetAllowZeroIn(b bool) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
if b {
c.inAllowZeroHop = "true"
return nil
}
c.inAllowZeroHop = "false"
return nil
}
}
//SetAllowZeroOut tells the tunnel to accept zero-hop peers
func SetAllowZeroOut(b bool) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
if b {
c.outAllowZeroHop = "true"
return nil
}
c.outAllowZeroHop = "false"
return nil
}
}
//SetCompress tells clients to use compression
func SetCompress(b bool) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
if b {
c.useCompression = "true"
return nil
}
c.useCompression = "false"
return nil
}
}
//SetFastRecieve tells clients to use compression
func SetFastRecieve(b bool) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
if b {
c.fastRecieve = "true"
return nil
}
c.fastRecieve = "false"
return nil
}
}
//SetReduceIdle tells the connection to reduce it's tunnels during extended idle time.
func SetReduceIdle(b bool) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
if b {
c.reduceIdle = "true"
return nil
}
c.reduceIdle = "false"
return nil
}
}
//SetReduceIdleTime sets the time to wait before reducing tunnels to idle levels
func SetReduceIdleTime(u int) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
c.reduceIdleTime = "300000"
if u >= 6 {
c.reduceIdleTime = strconv.Itoa((u * 60) * 1000)
return nil
}
return fmt.Errorf("Invalid reduce idle timeout(Measured in minutes) %v", u)
}
}
//SetReduceIdleTimeMs sets the time to wait before reducing tunnels to idle levels in milliseconds
func SetReduceIdleTimeMs(u int) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
c.reduceIdleTime = "300000"
if u >= 300000 {
c.reduceIdleTime = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid reduce idle timeout(Measured in milliseconds) %v", u)
}
}
//SetReduceIdleQuantity sets minimum number of tunnels to reduce to during idle time
func SetReduceIdleQuantity(u int) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
if u < 5 {
c.reduceIdleQuantity = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid reduce tunnel quantity")
}
}
//SetCloseIdle tells the connection to close it's tunnels during extended idle time.
func SetCloseIdle(b bool) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
if b {
c.closeIdle = "true"
return nil
}
c.closeIdle = "false"
return nil
}
}
//SetCloseIdleTime sets the time to wait before closing tunnels to idle levels
func SetCloseIdleTime(u int) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
c.closeIdleTime = "300000"
if u >= 6 {
c.closeIdleTime = strconv.Itoa((u * 60) * 1000)
return nil
}
return fmt.Errorf("Invalid close idle timeout(Measured in minutes) %v", u)
}
}
//SetCloseIdleTimeMs sets the time to wait before closing tunnels to idle levels in milliseconds
func SetCloseIdleTimeMs(u int) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
c.closeIdleTime = "300000"
if u >= 300000 {
c.closeIdleTime = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid close idle timeout(Measured in milliseconds) %v", u)
}
}
//SetAccessListType tells the system to treat the accessList as a whitelist
func SetAccessListType(s string) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
if s == "whitelist" {
c.accessListType = "whitelist"
return nil
} else if s == "blacklist" {
c.accessListType = "blacklist"
return nil
} else if s == "none" {
c.accessListType = ""
return nil
} else if s == "" {
c.accessListType = ""
return nil
}
return fmt.Errorf("Invalid Access list type(whitelist, blacklist, none)")
}
}
//SetAccessList tells the system to treat the accessList as a whitelist
func SetAccessList(s []string) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
if len(s) > 0 {
for _, a := range s {
c.accessList = append(c.accessList, a)
}
return nil
}
return nil
}
}
//SetTargetForPort sets the port of the SAMForwarder's SAM bridge using a string
/*func SetTargetForPort443(s string) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
port, err := strconv.Atoi(s)
if err != nil {
return fmt.Errorf("Invalid Target Port %s; non-number ", s)
}
if port < 65536 && port > -1 {
c.TargetForPort443 = s
return nil
}
return fmt.Errorf("Invalid port")
}
}
*/
//SetKeyFile sets
func SetKeyFile(s string) func(*SAMForwarder) error {
return func(c *SAMForwarder) error {
c.passfile = s
c.ByteLimit = u
return nil
}
}

View File

@ -2,6 +2,7 @@ package samforwarder
import (
"bufio"
"crypto/tls"
"io"
"log"
"net"
@ -14,68 +15,31 @@ import (
)
import (
"github.com/eyedeekay/sam-forwarder/config"
"github.com/eyedeekay/sam-forwarder/hashhash"
"github.com/eyedeekay/sam-forwarder/i2pkeys"
"github.com/eyedeekay/sam-forwarder/interface"
"github.com/eyedeekay/sam-forwarder/options"
"github.com/eyedeekay/sam3"
"github.com/eyedeekay/sam3/i2pkeys"
i2pkeys "github.com/eyedeekay/sam3/i2pkeys"
)
//SAMForwarder is a structure which automatically configured the forwarding of
//a local service to i2p over the SAM API.
type SAMForwarder struct {
SamHost string
SamPort string
TunName string
TargetHost string
TargetPort string
samConn *sam3.SAM
SamKeys i2pkeys.I2PKeys
Hasher *hashhash.Hasher
publishStream *sam3.StreamSession
publishListen *sam3.StreamListener
publishListen net.Listener //*sam3.StreamListener
Bytes map[string]int64
ByteLimit int64
FilePath string
file io.ReadWriter
save bool
up bool
file io.ReadWriter
up bool
Type string
// samcatd options
passfile string
sigType string
// I2CP options
encryptLeaseSet string
leaseSetKey string
leaseSetPrivateKey string
leaseSetPrivateSigningKey string
LeaseSetKeys *i2pkeys.I2PKeys
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
//Streaming Library options
accessListType string
accessList []string
// conf
Conf *i2ptunconf.Conf
clientLock bool
connLock bool
@ -86,8 +50,15 @@ type SAMForwarder struct {
var err error
func (f *SAMForwarder) Config() *i2ptunconf.Conf {
if f.Conf == nil {
f.Conf = i2ptunconf.NewI2PBlankTunConf()
}
return f.Conf
}
func (f *SAMForwarder) ID() string {
return f.TunName
return f.Config().TunName
}
func (f *SAMForwarder) Keys() i2pkeys.I2PKeys {
@ -101,7 +72,7 @@ func (f *SAMForwarder) Cleanup() {
}
func (f *SAMForwarder) GetType() string {
return f.Type
return f.Conf.Type
}
/*func (f *SAMForwarder) targetForPort443() string {
@ -112,7 +83,7 @@ func (f *SAMForwarder) GetType() string {
}*/
func (f *SAMForwarder) print() []string {
lsk, lspk, lspsk := f.leasesetsettings()
/*lsk, lspk, lspsk := f.Config().Leasesetsettings()
return []string{
//f.targetForPort443(),
"inbound.length=" + f.inLength,
@ -137,7 +108,8 @@ func (f *SAMForwarder) print() []string {
lsk, lspk, lspsk,
f.accesslisttype(),
f.accesslist(),
}
}*/
return f.Conf.PrintSlice()
}
func (f *SAMForwarder) Props() map[string]string {
@ -155,11 +127,11 @@ func (f *SAMForwarder) Props() map[string]string {
func (f *SAMForwarder) Print() string {
var r string
r += "name=" + f.TunName + "\n"
r += "type=" + f.Type + "\n"
r += "name=" + f.Config().TunName + "\n"
r += "type=" + f.Conf.Type + "\n"
r += "base32=" + f.Base32() + "\n"
r += "base64=" + f.Base64() + "\n"
if f.Type == "http" {
if f.Conf.Type == "http" || f.Conf.Type == "https" {
r += "httpserver\n"
} else {
r += "ntcpserver\n"
@ -184,20 +156,20 @@ func (f *SAMForwarder) Search(search string) string {
}
func (f *SAMForwarder) accesslisttype() string {
if f.accessListType == "whitelist" {
if f.Config().AccessListType == "allowlist" {
return "i2cp.enableAccessList=true"
} else if f.accessListType == "blacklist" {
} else if f.Config().AccessListType == "blocklist" {
return "i2cp.enableBlackList=true"
} else if f.accessListType == "none" {
} else if f.Config().AccessListType == "none" {
return ""
}
return ""
}
func (f *SAMForwarder) accesslist() string {
if f.accessListType != "" && len(f.accessList) > 0 {
if f.Config().AccessListType != "" && len(f.Config().AccessList) > 0 {
r := ""
for _, s := range f.accessList {
for _, s := range f.Config().AccessList {
r += s + ","
}
return "i2cp.accessList=" + strings.TrimSuffix(r, ",")
@ -207,28 +179,33 @@ func (f *SAMForwarder) accesslist() string {
func (f *SAMForwarder) leasesetsettings() (string, string, string) {
var r, s, t string
if f.leaseSetKey != "" {
r = "i2cp.leaseSetKey=" + f.leaseSetKey
if f.Config().LeaseSetKey != "" {
r = "i2cp.leaseSetKey=" + f.Config().LeaseSetKey
}
if f.leaseSetPrivateKey != "" {
s = "i2cp.leaseSetPrivateKey=" + f.leaseSetPrivateKey
if f.Config().LeaseSetPrivateKey != "" {
s = "i2cp.leaseSetPrivateKey=" + f.Config().LeaseSetPrivateKey
}
if f.leaseSetPrivateSigningKey != "" {
t = "i2cp.leaseSetPrivateSigningKey=" + f.leaseSetPrivateSigningKey
if f.Config().LeaseSetPrivateSigningKey != "" {
t = "i2cp.leaseSetPrivateSigningKey=" + f.Config().LeaseSetPrivateSigningKey
}
return r, s, t
}
// Target returns the host:port of the local service you want to forward to i2p
func (f *SAMForwarder) Target() string {
return f.TargetHost + ":" + f.TargetPort
return f.Config().TargetHost + ":" + f.Config().TargetPort
}
func (f *SAMForwarder) sam() string {
return f.SamHost + ":" + f.SamPort
return f.Config().SamHost + ":" + f.Config().SamPort
}
func (f *SAMForwarder) HTTPRequestBytes(conn *sam3.SAMConn) ([]byte, *http.Request, error) {
func (f *SAMForwarder) ClientBase64(conn net.Conn) string {
dest := conn.RemoteAddr().(i2pkeys.I2PAddr)
return dest.Base32()
}
func (f *SAMForwarder) HTTPRequestBytes(conn net.Conn) ([]byte, *http.Request, error) {
var request *http.Request
var retrequest []byte
var err error
@ -239,7 +216,7 @@ func (f *SAMForwarder) HTTPRequestBytes(conn *sam3.SAMConn) ([]byte, *http.Reque
dest := conn.RemoteAddr().(i2pkeys.I2PAddr)
request.Header.Add("X-I2p-Dest-Base64", dest.Base64())
request.Header.Add("X-I2p-Dest-Base32", dest.Base32())
request.Header.Add("X-I2p-Dest-Hash", dest.DestHash().String())
request.Header.Add("X-I2p-Dest-Hash", dest.DestHash().Hash())
if retrequest, err = httputil.DumpRequest(request, true); err != nil {
return nil, nil, err
}
@ -254,8 +231,6 @@ func (f *SAMForwarder) HTTPResponseBytes(conn net.Conn, req *http.Request) ([]by
if err != nil {
return nil, err
}
response.Header.Add("X-I2p-Dest-Base64", f.Base64())
response.Header.Add("X-I2p-Dest-Base32", f.Base32())
if retresponse, err = httputil.DumpResponse(response, true); err != nil {
return nil, err
}
@ -276,7 +251,7 @@ func (f *SAMForwarder) clientUnlockAndClose(cli, conn bool, client net.Conn) {
}
}
func (f *SAMForwarder) connUnlockAndClose(cli, conn bool, connection *sam3.SAMConn) {
func (f *SAMForwarder) connUnlockAndClose(cli, conn bool, connection net.Conn) {
if cli {
f.connClientLock = cli
}
@ -290,7 +265,7 @@ func (f *SAMForwarder) connUnlockAndClose(cli, conn bool, connection *sam3.SAMCo
}
}
func (f *SAMForwarder) forward(conn *sam3.SAMConn) { //(conn net.Conn) {
func (f *SAMForwarder) forward(conn net.Conn) { //(conn net.Conn) {
if !f.Up() {
return
}
@ -303,7 +278,7 @@ func (f *SAMForwarder) forward(conn *sam3.SAMConn) { //(conn net.Conn) {
log.Fatalf("Dial failed: %v", err)
}
go func() {
if f.Type == "http" {
if f.Conf.Type == "http" || f.Conf.Type == "https" {
defer f.clientUnlockAndClose(true, false, client)
defer f.connUnlockAndClose(false, true, conn)
if requestbytes, request, err = f.HTTPRequestBytes(conn); err == nil {
@ -315,11 +290,22 @@ func (f *SAMForwarder) forward(conn *sam3.SAMConn) { //(conn net.Conn) {
} else {
defer client.Close()
defer conn.Close()
io.Copy(client, conn)
if f.ByteLimit > 0 {
if val, ok := f.Bytes[f.ClientBase64(conn)]; ok == true {
if val > f.ByteLimit {
return
}
}
}
if count, err := io.Copy(client, conn); err == nil {
if f.ByteLimit > 0 {
f.Bytes[f.ClientBase64(conn)] += count
}
}
}
}()
go func() {
if f.Type == "http" {
if f.Conf.Type == "http" || f.Conf.Type == "https" {
defer f.clientUnlockAndClose(false, true, client)
defer f.connUnlockAndClose(true, false, conn)
if responsebytes, err = f.HTTPResponseBytes(client, request); err == nil {
@ -331,6 +317,11 @@ func (f *SAMForwarder) forward(conn *sam3.SAMConn) { //(conn net.Conn) {
} else {
defer client.Close()
defer conn.Close()
if val, ok := f.Bytes[f.ClientBase64(conn)]; ok == true {
if val > f.ByteLimit {
return
}
}
io.Copy(conn, client)
}
}()
@ -355,22 +346,31 @@ func (f *SAMForwarder) Base64() string {
//Serve starts the SAM connection and and forwards the local host:port to i2p
func (f *SAMForwarder) Serve() error {
//lsk, lspk, lspsk := f.leasesetsettings()
//lsk, lspk, lspsk := f.Config().Leasesetsettings()
if f.Up() {
if f.publishStream, err = f.samConn.NewStreamSession(f.TunName, f.SamKeys, f.print()); err != nil {
if f.publishStream, err = f.samConn.NewStreamSession(f.Conf.TunName, f.SamKeys, f.print()); err != nil {
log.Println("Stream Creation error:", err.Error())
return err
}
log.Println("SAM stream session established.")
if f.publishListen, err = f.publishStream.Listen(); err != nil {
publishListen, err := f.publishStream.Listen()
if err != nil {
return err
}
log.Println("Starting Listener.")
log.Println("SAM Listener created,", f.Base32())
log.Println("Human-readable hash:\n ", f.Base32Readable())
if f.Conf.UseTLS {
tlsconf, err := f.Conf.TLSConfig()
if err != nil {
return err
}
f.publishListen = tls.NewListener(publishListen, tlsconf)
} else {
f.publishListen = publishListen
}
for {
conn, err := f.publishListen.AcceptI2P()
conn, err := f.publishListen.Accept()
if err != nil {
log.Printf("ERROR: failed to accept listener: %v", err)
return nil
@ -403,18 +403,18 @@ func (s *SAMForwarder) Load() (samtunnel.SAMTunnel, error) {
return nil, err
}
log.Println("SAM Bridge connection established.")
if s.save {
if s.Conf.SaveFile {
log.Println("Saving i2p keys")
}
if s.SamKeys, err = sfi2pkeys.Load(s.FilePath, s.TunName, s.passfile, s.samConn, s.save); err != nil {
if s.SamKeys, err = sfi2pkeys.Load(s.Conf.FilePath, s.Conf.TunName, s.Conf.KeyFilePath, s.samConn, s.Conf.SaveFile); err != nil {
return nil, err
}
log.Println("Destination keys generated, tunnel name:", s.TunName)
if s.save {
if err := sfi2pkeys.Save(s.FilePath, s.TunName, s.passfile, s.SamKeys); err != nil {
log.Println("Destination keys generated, tunnel name:", s.Conf.TunName)
if s.Conf.SaveFile {
if err := sfi2pkeys.Save(s.Conf.FilePath, s.Conf.TunName, s.Conf.KeyFilePath, s.SamKeys); err != nil {
return nil, err
}
log.Println("Saved tunnel keys for", s.TunName)
log.Println("Saved tunnel keys for", s.Conf.TunName, "in", s.Conf.FilePath)
}
s.Hasher, err = hashhash.NewHasher(len(strings.Replace(s.Base32(), ".b32.i2p", "", 1)))
if err != nil {
@ -425,46 +425,18 @@ func (s *SAMForwarder) Load() (samtunnel.SAMTunnel, error) {
}
//NewSAMForwarder makes a new SAM forwarder with default options, accepts host:port arguments
func NewSAMForwarder(host, port string) (*SAMForwarder, error) {
return NewSAMForwarderFromOptions(SetHost(host), SetPort(port))
func NewSAMForwarder(host, port string) (samtunnel.SAMTunnel, error) {
return NewSAMForwarderFromOptions(samoptions.SetHost(host), samoptions.SetPort(port))
}
//NewSAMForwarderFromOptions makes a new SAM forwarder with default options, accepts host:port arguments
func NewSAMForwarderFromOptions(opts ...func(*SAMForwarder) error) (*SAMForwarder, error) {
func NewSAMForwarderFromOptions(opts ...func(samtunnel.SAMTunnel) error) (*SAMForwarder, error) {
var s SAMForwarder
s.SamHost = "127.0.0.1"
s.SamPort = "7656"
s.FilePath = ""
s.save = false
s.TargetHost = "127.0.0.1"
s.TargetPort = "8081"
s.TunName = "samForwarder"
s.Type = "server"
s.inLength = "3"
s.outLength = "3"
s.inQuantity = "2"
s.outQuantity = "2"
s.inVariance = "1"
s.outVariance = "1"
s.inBackupQuantity = "3"
s.outBackupQuantity = "3"
s.inAllowZeroHop = "false"
s.outAllowZeroHop = "false"
s.encryptLeaseSet = "false"
s.leaseSetKey = ""
s.leaseSetPrivateKey = ""
s.leaseSetPrivateSigningKey = ""
s.fastRecieve = "false"
s.useCompression = "true"
s.reduceIdle = "false"
s.reduceIdleTime = "15"
s.reduceIdleQuantity = "4"
s.closeIdle = "false"
s.closeIdleTime = "300000"
s.Conf = i2ptunconf.NewI2PBlankTunConf()
s.clientLock = false
s.connLock = false
s.messageReliability = "none"
s.passfile = ""
s.ByteLimit = -1
s.Bytes = make(map[string]int64)
for _, o := range opts {
if err := o(&s); err != nil {
return nil, err

View File

@ -3,10 +3,12 @@ package samforwarder
import (
"log"
"testing"
"github.com/eyedeekay/sam-forwarder/options"
)
func TestOptionHost(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetHost("127.0.0.1"))
client, err := NewSAMForwarderFromOptions(samoptions.SetHost("127.0.0.1"))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -14,7 +16,7 @@ func TestOptionHost(t *testing.T) {
}
func TestOptionPort(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetPort("8080"))
client, err := NewSAMForwarderFromOptions(samoptions.SetPort("8080"))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -22,7 +24,7 @@ func TestOptionPort(t *testing.T) {
}
func TestOptionInLength(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetInLength(3))
client, err := NewSAMForwarderFromOptions(samoptions.SetInLength(3))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -30,7 +32,7 @@ func TestOptionInLength(t *testing.T) {
}
func TestOptionOutLength(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetInLength(3))
client, err := NewSAMForwarderFromOptions(samoptions.SetInLength(3))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -38,7 +40,7 @@ func TestOptionOutLength(t *testing.T) {
}
func TestOptionInVariance(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetInVariance(1))
client, err := NewSAMForwarderFromOptions(samoptions.SetInVariance(1))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -46,7 +48,7 @@ func TestOptionInVariance(t *testing.T) {
}
func TestOptionOutVariance(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetOutVariance(1))
client, err := NewSAMForwarderFromOptions(samoptions.SetOutVariance(1))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -54,7 +56,7 @@ func TestOptionOutVariance(t *testing.T) {
}
func TestOptionInQuantity(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetInQuantity(6))
client, err := NewSAMForwarderFromOptions(samoptions.SetInQuantity(6))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -62,7 +64,7 @@ func TestOptionInQuantity(t *testing.T) {
}
func TestOptionOutQuantity(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetOutQuantity(6))
client, err := NewSAMForwarderFromOptions(samoptions.SetOutQuantity(6))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -70,7 +72,7 @@ func TestOptionOutQuantity(t *testing.T) {
}
func TestOptionInBackups(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetInBackups(5))
client, err := NewSAMForwarderFromOptions(samoptions.SetInBackups(5))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -78,7 +80,7 @@ func TestOptionInBackups(t *testing.T) {
}
func TestOptionOutBackups(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetOutBackups(5))
client, err := NewSAMForwarderFromOptions(samoptions.SetOutBackups(5))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -86,7 +88,7 @@ func TestOptionOutBackups(t *testing.T) {
}
func TestOptionReduceIdleQuantity(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetReduceIdleQuantity(4))
client, err := NewSAMForwarderFromOptions(samoptions.SetReduceIdleQuantity(4))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -94,7 +96,7 @@ func TestOptionReduceIdleQuantity(t *testing.T) {
}
func TestOptionReduceIdleTimeMs(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetReduceIdleTimeMs(300000))
client, err := NewSAMForwarderFromOptions(samoptions.SetReduceIdleTimeMs(300000))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -102,7 +104,7 @@ func TestOptionReduceIdleTimeMs(t *testing.T) {
}
func TestOptionReduceIdleTime(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetReduceIdleTime(6))
client, err := NewSAMForwarderFromOptions(samoptions.SetReduceIdleTime(6))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -110,7 +112,7 @@ func TestOptionReduceIdleTime(t *testing.T) {
}
func TestOptionCloseIdleTimeMs(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetCloseIdleTimeMs(300000))
client, err := NewSAMForwarderFromOptions(samoptions.SetCloseIdleTimeMs(300000))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -118,7 +120,7 @@ func TestOptionCloseIdleTimeMs(t *testing.T) {
}
func TestOptionCloseIdleTime(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetCloseIdleTime(6))
client, err := NewSAMForwarderFromOptions(samoptions.SetCloseIdleTime(6))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -126,7 +128,7 @@ func TestOptionCloseIdleTime(t *testing.T) {
}
func TestOptionEncryptLease(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetEncrypt(true))
client, err := NewSAMForwarderFromOptions(samoptions.SetEncrypt(true))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -134,7 +136,7 @@ func TestOptionEncryptLease(t *testing.T) {
}
func TestOptionSaveFile(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetSaveFile(true))
client, err := NewSAMForwarderFromOptions(samoptions.SetSaveFile(true))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -142,7 +144,7 @@ func TestOptionSaveFile(t *testing.T) {
}
func TestClientOptionHost(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientHost("127.0.0.1"))
client, err := NewSAMClientForwarderFromOptions(samoptions.SetHost("127.0.0.1"))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -150,7 +152,7 @@ func TestClientOptionHost(t *testing.T) {
}
func TestClientOptionPort(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientSAMPort("7656"))
client, err := NewSAMClientForwarderFromOptions(samoptions.SetSAMPort("7656"))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -158,7 +160,7 @@ func TestClientOptionPort(t *testing.T) {
}
func TestClientOptionInLength(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientInLength(3))
client, err := NewSAMClientForwarderFromOptions(samoptions.SetInLength(3))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -166,7 +168,7 @@ func TestClientOptionInLength(t *testing.T) {
}
func TestClientOptionOutLength(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientInLength(3))
client, err := NewSAMClientForwarderFromOptions(samoptions.SetInLength(3))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -174,7 +176,7 @@ func TestClientOptionOutLength(t *testing.T) {
}
func TestClientOptionInVariance(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientInVariance(1))
client, err := NewSAMClientForwarderFromOptions(samoptions.SetInVariance(1))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -182,7 +184,7 @@ func TestClientOptionInVariance(t *testing.T) {
}
func TestClientOptionOutVariance(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientOutVariance(1))
client, err := NewSAMClientForwarderFromOptions(samoptions.SetOutVariance(1))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -190,7 +192,7 @@ func TestClientOptionOutVariance(t *testing.T) {
}
func TestClientOptionInQuantity(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientInQuantity(6))
client, err := NewSAMClientForwarderFromOptions(samoptions.SetInQuantity(6))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -198,7 +200,7 @@ func TestClientOptionInQuantity(t *testing.T) {
}
func TestClientOptionOutQuantity(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientOutQuantity(6))
client, err := NewSAMClientForwarderFromOptions(samoptions.SetOutQuantity(6))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -206,7 +208,7 @@ func TestClientOptionOutQuantity(t *testing.T) {
}
func TestClientOptionInBackups(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientInBackups(5))
client, err := NewSAMClientForwarderFromOptions(samoptions.SetInBackups(5))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -214,7 +216,7 @@ func TestClientOptionInBackups(t *testing.T) {
}
func TestClientOptionOutBackups(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientOutBackups(5))
client, err := NewSAMClientForwarderFromOptions(samoptions.SetOutBackups(5))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -222,7 +224,7 @@ func TestClientOptionOutBackups(t *testing.T) {
}
func TestClientOptionReduceIdleQuantity(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientReduceIdleQuantity(4))
client, err := NewSAMClientForwarderFromOptions(samoptions.SetReduceIdleQuantity(4))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -230,7 +232,7 @@ func TestClientOptionReduceIdleQuantity(t *testing.T) {
}
func TestClientOptionReduceIdleTimeMs(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientReduceIdleTimeMs(300000))
client, err := NewSAMClientForwarderFromOptions(samoptions.SetReduceIdleTimeMs(300000))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -238,7 +240,7 @@ func TestClientOptionReduceIdleTimeMs(t *testing.T) {
}
func TestClientOptionReduceIdleTime(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientReduceIdleTime(6))
client, err := NewSAMClientForwarderFromOptions(samoptions.SetReduceIdleTime(6))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -246,7 +248,7 @@ func TestClientOptionReduceIdleTime(t *testing.T) {
}
func TestClientOptionCloseIdleTimeMs(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientCloseIdleTimeMs(300000))
client, err := NewSAMClientForwarderFromOptions(samoptions.SetCloseIdleTimeMs(300000))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -254,7 +256,7 @@ func TestClientOptionCloseIdleTimeMs(t *testing.T) {
}
func TestClientOptionCloseIdleTime(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientCloseIdleTime(6))
client, err := NewSAMClientForwarderFromOptions(samoptions.SetCloseIdleTime(6))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -262,7 +264,7 @@ func TestClientOptionCloseIdleTime(t *testing.T) {
}
func TestClientOptionEncryptLease(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientEncrypt(true))
client, err := NewSAMClientForwarderFromOptions(samoptions.SetEncrypt(true))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -270,7 +272,7 @@ func TestClientOptionEncryptLease(t *testing.T) {
}
func TestClientOptionSaveFile(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientSaveFile(true))
client, err := NewSAMClientForwarderFromOptions(samoptions.SetSaveFile(true))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -278,7 +280,7 @@ func TestClientOptionSaveFile(t *testing.T) {
}
/*func TestOptionTargetForPort443(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetTargetForPort443("443"))
client, err := NewSAMForwarderFromOptions(samoptions.SetTargetForPort443("443"))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}

100
tls/tls.go Normal file
View File

@ -0,0 +1,100 @@
package i2ptls
import (
"crypto/ed25519"
"crypto/rand"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"log"
"math/big"
"os"
)
func CheckFile(path string) bool {
if _, err := os.Stat(path); os.IsNotExist(err) {
return false
}
return true
}
func CertPemificate(CertPem, KeyPem string, names []string, priv ed25519.PrivateKey) (tls.Certificate, error) {
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
log.Fatalf("Failed to generate serial number: %v", err)
}
template := x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
Organization: []string{"Acme Co"},
},
// NotBefore: notBefore,
// NotAfter: notAfter,
// KeyUsage: keyUsage,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
}
if len(names) > 0 {
template.DNSNames = append(template.DNSNames, names...)
}
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, priv.Public().(ed25519.PublicKey), priv)
if err != nil {
log.Fatalf("Failed to create certificate: %v", err)
}
certOut, err := os.Create(CertPem)
if err != nil {
log.Fatalf("Failed to open "+CertPem+" for writing: %v", err)
}
if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil {
log.Fatalf("Failed to write data to "+CertPem+": %v", err)
}
if err := certOut.Close(); err != nil {
log.Fatalf("Error closing "+CertPem+": %v", err)
}
log.Print("wrote " + CertPem + "\n")
keyOut, err := os.OpenFile(KeyPem, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
log.Fatalf("Failed to open "+KeyPem+" for writing: %v", err)
}
privBytes, err := x509.MarshalPKCS8PrivateKey(priv)
if err != nil {
log.Fatalf("Unable to marshal private key: %v", err)
}
if err := pem.Encode(keyOut, &pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}); err != nil {
log.Fatalf("Failed to write data to key.pem: %v", err)
}
if err := keyOut.Close(); err != nil {
log.Fatalf("Error closing key.pem: %v", err)
}
return tls.LoadX509KeyPair(CertPem, KeyPem)
}
func TLSConfig(CertPem, KeyPem string, names []string) (*tls.Config, error) {
var ServerName string
if len(names) > 0 {
ServerName = names[0]
}
if CheckFile(CertPem) && CheckFile(KeyPem) {
cert, err := tls.LoadX509KeyPair(CertPem, KeyPem)
if err != nil {
return nil, err
}
return &tls.Config{Certificates: []tls.Certificate{cert}, ServerName: ServerName}, nil
} else {
_, priv, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
return nil, err
}
cert, err := CertPemificate(CertPem, KeyPem, names, priv)
if err != nil {
return nil, err
}
return &tls.Config{Certificates: []tls.Certificate{cert}, ServerName: ServerName}, nil
}
}

11
tls/tls_test.go Normal file
View File

@ -0,0 +1,11 @@
package i2ptls
import "testing"
func TestTLSGenerate(t *testing.T) {
config, err := TLSConfig("cert.pem", "key.pem", []string{"idk.i2p"})
if err != nil {
t.Fatal(err.Error())
}
t.Log(config.ServerName)
}

View File

@ -1,413 +0,0 @@
package samforwarderudp
import (
"fmt"
"strconv"
)
//ClientOption is a SAMSSUClientForwarder Option
type ClientOption func(*SAMSSUClientForwarder) error
//SetClientFilePath sets the host of the SAMSSUForwarder's SAM bridge
func SetClientFilePath(s string) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
c.FilePath = s
return nil
}
}
//SetClientSaveFile tells the router to use an encrypted leaseset
func SetClientSaveFile(b bool) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
c.save = b
return nil
}
}
//SetClientHost sets the host of the SAMSSUForwarder's SAM bridge
func SetClientHost(s string) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
c.TargetHost = s
return nil
}
}
//SetClientPort sets the port of the SAMSSUForwarder's SAM bridge using a string
func SetClientPort(s string) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
port, err := strconv.Atoi(s)
if err != nil {
return fmt.Errorf("Invalid SSU Client Target Port %s; non-number ", s)
}
if port < 65536 && port > -1 {
c.TargetPort = s
return nil
}
return fmt.Errorf("Invalid port")
}
}
//SetClientSAMHost sets the host of the SAMSSUForwarder's SAM bridge
func SetClientSAMHost(s string) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
c.SamHost = s
return nil
}
}
//SetClientSAMPort sets the port of the SAMSSUForwarder's SAM bridge using a string
func SetClientSAMPort(s string) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
port, err := strconv.Atoi(s)
if err != nil {
return fmt.Errorf("Invalid SAM Port %s; non-number", s)
}
if port < 65536 && port > -1 {
c.SamPort = s
return nil
}
return fmt.Errorf("Invalid port")
}
}
//SetClientDestination sets the destination to forwarder SAMClientForwarder's to
func SetClientDestination(s string) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
c.dest = s
return nil
}
}
//SetClientName sets the host of the SAMSSUForwarder's SAM bridge
func SetClientName(s string) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
c.TunName = s
return nil
}
}
//SetClientSigType sets the type of the forwarder server
func SetClientSigType(s string) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
if s == "" {
c.sigType = ""
} else if s == "DSA_SHA1" {
c.sigType = "DSA_SHA1"
} else if s == "ECDSA_SHA256_P256" {
c.sigType = "ECDSA_SHA256_P256"
} else if s == "ECDSA_SHA384_P384" {
c.sigType = "ECDSA_SHA384_P384"
} else if s == "ECDSA_SHA512_P521" {
c.sigType = "ECDSA_SHA512_P521"
} else if s == "EdDSA_SHA512_Ed25519" {
c.sigType = "EdDSA_SHA512_Ed25519"
} else {
c.sigType = "EdDSA_SHA512_Ed25519"
}
return nil
}
}
//SetClientInLength sets the number of hops inbound
func SetClientInLength(u int) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
if u < 7 && u >= 0 {
c.inLength = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid inbound tunnel length")
}
}
//SetClientOutLength sets the number of hops outbound
func SetClientOutLength(u int) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
if u < 7 && u >= 0 {
c.outLength = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid outbound tunnel length")
}
}
//SetClientInVariance sets the variance of a number of hops inbound
func SetClientInVariance(i int) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
if i < 7 && i > -7 {
c.inVariance = strconv.Itoa(i)
return nil
}
return fmt.Errorf("Invalid inbound tunnel length")
}
}
//SetClientOutVariance sets the variance of a number of hops outbound
func SetClientOutVariance(i int) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
if i < 7 && i > -7 {
c.outVariance = strconv.Itoa(i)
return nil
}
return fmt.Errorf("Invalid outbound tunnel variance")
}
}
//SetClientInQuantity sets the inbound tunnel quantity
func SetClientInQuantity(u int) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
if u <= 16 && u > 0 {
c.inQuantity = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid inbound tunnel quantity")
}
}
//SetClientOutQuantity sets the outbound tunnel quantity
func SetClientOutQuantity(u int) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
if u <= 16 && u > 0 {
c.outQuantity = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid outbound tunnel quantity")
}
}
//SetClientInBackups sets the inbound tunnel backups
func SetClientInBackups(u int) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
if u < 6 && u >= 0 {
c.inBackupQuantity = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid inbound tunnel backup quantity")
}
}
//SetClientOutBackups sets the inbound tunnel backups
func SetClientOutBackups(u int) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
if u < 6 && u >= 0 {
c.outBackupQuantity = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid outbound tunnel backup quantity")
}
}
//SetClientEncrypt tells the router to use an encrypted leaseset
func SetClientEncrypt(b bool) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
if b {
c.encryptLeaseSet = "true"
return nil
}
c.encryptLeaseSet = "false"
return nil
}
}
//SetClientLeaseSetKey sets the host of the SAMForwarder's SAM bridge
func SetClientLeaseSetKey(s string) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
c.leaseSetKey = s
return nil
}
}
//SetClientLeaseSetPrivateKey sets the host of the SAMForwarder's SAM bridge
func SetClientLeaseSetPrivateKey(s string) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
c.leaseSetPrivateKey = s
return nil
}
}
//SetClientLeaseSetPrivateSigningKey sets the host of the SAMForwarder's SAM bridge
func SetClientLeaseSetPrivateSigningKey(s string) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
c.leaseSetPrivateSigningKey = s
return nil
}
}
//SetClientMessageReliability sets
func SetClientMessageReliability(s string) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
c.messageReliability = s
return nil
}
}
//SetClientAllowZeroIn tells the tunnel to accept zero-hop peers
func SetClientAllowZeroIn(b bool) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
if b {
c.inAllowZeroHop = "true"
return nil
}
c.inAllowZeroHop = "false"
return nil
}
}
//SetClientAllowZeroOut tells the tunnel to accept zero-hop peers
func SetClientAllowZeroOut(b bool) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
if b {
c.outAllowZeroHop = "true"
return nil
}
c.outAllowZeroHop = "false"
return nil
}
}
//SetFastRecieve tells clients to use i2cp.fastRecieve
func SetClientFastRecieve(b bool) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
if b {
c.fastRecieve = "true"
return nil
}
c.fastRecieve = "false"
return nil
}
}
//SetClientCompress tells clients to use compression
func SetClientCompress(b bool) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
if b {
c.useCompression = "true"
return nil
}
c.useCompression = "false"
return nil
}
}
//SetClientReduceIdle tells the connection to reduce it's tunnels during extended idle time.
func SetClientReduceIdle(b bool) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
if b {
c.reduceIdle = "true"
return nil
}
c.reduceIdle = "false"
return nil
}
}
//SetClientReduceIdleTime sets the time to wait before reducing tunnels to idle levels
func SetClientReduceIdleTime(u int) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
c.reduceIdleTime = "300000"
if u >= 6 {
c.reduceIdleTime = strconv.Itoa((u * 60) * 1000)
return nil
}
return fmt.Errorf("Invalid reduce idle timeout(Measured in minutes)")
}
}
//SetClientReduceIdleTimeMs sets the time to wait before reducing tunnels to idle levels in milliseconds
func SetClientReduceIdleTimeMs(u int) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
c.reduceIdleTime = "300000"
if u >= 300000 {
c.reduceIdleTime = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid reduce idle timeout(Measured in minutes)")
}
}
//SetClientReduceIdleQuantity sets minimum number of tunnels to reduce to during idle time
func SetClientReduceIdleQuantity(u int) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
if u < 5 {
c.reduceIdleQuantity = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid reduce tunnel quantity")
}
}
//SetClientCloseIdle tells the connection to close it's tunnels during extended idle time.
func SetClientCloseIdle(b bool) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
if b {
c.closeIdle = "true"
return nil
}
c.closeIdle = "false"
return nil
}
}
//SetClientCloseIdleTime sets the time to wait before closing tunnels to idle levels
func SetClientCloseIdleTime(u int) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
c.closeIdleTime = "300000"
if u >= 6 {
c.closeIdleTime = strconv.Itoa((u * 60) * 1000)
return nil
}
return fmt.Errorf("Invalid close idle timeout(Measured in minutes) %v", u)
}
}
//SetClientCloseIdleTimeMs sets the time to wait before closing tunnels to idle levels in milliseconds
func SetClientCloseIdleTimeMs(u int) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
c.closeIdleTime = "300000"
if u >= 300000 {
c.closeIdleTime = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid close idle timeout(Measured in milliseconds) %v", u)
}
}
//SetClientAccessListType tells the system to treat the accessList as a whitelist
func SetClientAccessListType(s string) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
if s == "whitelist" {
c.accessListType = "whitelist"
return nil
} else if s == "blacklist" {
c.accessListType = "blacklist"
return nil
} else if s == "none" {
c.accessListType = ""
return nil
} else if s == "" {
c.accessListType = ""
return nil
}
return fmt.Errorf("Invalid Access list type(whitelist, blacklist, none)")
}
}
//SetClientAccessList tells the system to treat the accessList as a whitelist
func SetClientAccessList(s []string) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
if len(s) > 0 {
for _, a := range s {
c.accessList = append(c.accessList, a)
}
return nil
}
return nil
}
}
//SetKeyFile sets
func SetClientPassword(s string) func(*SAMSSUClientForwarder) error {
return func(c *SAMSSUClientForwarder) error {
c.passfile = s
return nil
}
}

View File

@ -1,135 +1,78 @@
package samforwarderudp
import (
"fmt"
"io"
"log"
"net"
//"os"
//"path/filepath"
"strconv"
"strings"
"time"
)
import (
"github.com/eyedeekay/sam-forwarder/config"
"github.com/eyedeekay/sam-forwarder/hashhash"
"github.com/eyedeekay/sam-forwarder/i2pkeys"
"github.com/eyedeekay/sam-forwarder/interface"
"github.com/eyedeekay/sam-forwarder/options"
"github.com/eyedeekay/sam3"
"github.com/eyedeekay/sam3/i2pkeys"
i2pkeys "github.com/eyedeekay/sam3/i2pkeys"
)
//SAMSSUClientForwarder is a structure which automatically configured the forwarding of
//SAMDGClientForwarder is a structure which automatically configured the forwarding of
//a local port to i2p over the SAM API.
type SAMSSUClientForwarder struct {
SamHost string
SamPort string
TunName string
Type string
TargetHost string
TargetPort string
type SAMDGClientForwarder struct {
samConn *sam3.SAM
SamKeys i2pkeys.I2PKeys
Hasher *hashhash.Hasher
connectStream *sam3.DatagramSession
dest string
addr i2pkeys.I2PAddr
publishConnection net.PacketConn
FilePath string
file io.ReadWriter
save bool
up bool
file io.ReadWriter
up bool
// samcatd options
passfile string
sigType string
// I2CP options
encryptLeaseSet string
leaseSetKey string
leaseSetPrivateKey string
leaseSetPrivateSigningKey string
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
//Streaming Library options
accessListType string
accessList []string
// config
Conf *i2ptunconf.Conf
}
func (f *SAMSSUClientForwarder) GetType() string {
return f.Type
func (f *SAMDGClientForwarder) Config() *i2ptunconf.Conf {
if f.Conf == nil {
f.Conf = i2ptunconf.NewI2PBlankTunConf()
}
return f.Conf
}
func (f *SAMSSUClientForwarder) ID() string {
return f.TunName
func (f *SAMDGClientForwarder) GetType() string {
return f.Config().Type
}
func (f *SAMSSUClientForwarder) Keys() i2pkeys.I2PKeys {
func (f *SAMDGClientForwarder) ID() string {
return f.Config().TunName
}
func (f *SAMDGClientForwarder) Keys() i2pkeys.I2PKeys {
return f.SamKeys
}
func (f *SAMSSUClientForwarder) Cleanup() {
func (f *SAMDGClientForwarder) Cleanup() {
f.publishConnection.Close()
f.connectStream.Close()
f.samConn.Close()
}
func (f *SAMSSUClientForwarder) Close() error {
func (f *SAMDGClientForwarder) Close() error {
f.Cleanup()
f.up = false
return nil
}
func (f *SAMSSUClientForwarder) print() []string {
lsk, lspk, lspsk := f.leasesetsettings()
return []string{
//f.targetForPort443(),
"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,
"inbound.allowZeroHop=" + f.inAllowZeroHop,
"outbound.allowZeroHop=" + f.outAllowZeroHop,
"i2cp.fastRecieve=" + f.fastRecieve,
"i2cp.gzip=" + f.useCompression,
"i2cp.reduceOnIdle=" + f.reduceIdle,
"i2cp.reduceIdleTime=" + f.reduceIdleTime,
"i2cp.reduceQuantity=" + f.reduceIdleQuantity,
"i2cp.closeOnIdle=" + f.closeIdle,
"i2cp.closeIdleTime=" + f.closeIdleTime,
"i2cp.messageReliability=" + f.messageReliability,
"i2cp.encryptLeaseSet=" + f.encryptLeaseSet,
lsk, lspk, lspsk,
f.accesslisttype(),
f.accesslist(),
}
func (f *SAMDGClientForwarder) print() []string {
return f.Config().PrintSlice()
}
func (f *SAMSSUClientForwarder) Props() map[string]string {
func (f *SAMDGClientForwarder) Props() map[string]string {
r := make(map[string]string)
print := f.print()
print = append(print, "base32="+f.Base32())
@ -142,13 +85,13 @@ func (f *SAMSSUClientForwarder) Props() map[string]string {
return r
}
func (f *SAMSSUClientForwarder) Print() string {
func (f *SAMDGClientForwarder) Print() string {
var r string
r += "name=" + f.TunName + "\n"
r += "type=" + f.Type + "\n"
r += "name=" + f.Config().TunName + "\n"
r += "type=" + f.Config().Type + "\n"
r += "base32=" + f.Base32() + "\n"
r += "base64=" + f.Base64() + "\n"
r += "dest=" + f.dest + "\n"
r += "dest=" + f.Config().ClientDest + "\n"
r += "ssuclient\n"
for _, s := range f.print() {
r += s + "\n"
@ -156,7 +99,7 @@ func (f *SAMSSUClientForwarder) Print() string {
return strings.Replace(r, "\n\n", "\n", -1)
}
func (f *SAMSSUClientForwarder) Search(search string) string {
func (f *SAMDGClientForwarder) Search(search string) string {
terms := strings.Split(search, ",")
if search == "" {
return f.Print()
@ -169,21 +112,21 @@ func (f *SAMSSUClientForwarder) Search(search string) string {
return f.Print()
}
func (f *SAMSSUClientForwarder) accesslisttype() string {
if f.accessListType == "whitelist" {
func (f *SAMDGClientForwarder) accesslisttype() string {
if f.Config().AccessListType == "allowlist" {
return "i2cp.enableAccessList=true"
} else if f.accessListType == "blacklist" {
} else if f.Config().AccessListType == "blocklist" {
return "i2cp.enableBlackList=true"
} else if f.accessListType == "none" {
} else if f.Config().AccessListType == "none" {
return ""
}
return ""
}
func (f *SAMSSUClientForwarder) accesslist() string {
if f.accessListType != "" && len(f.accessList) > 0 {
func (f *SAMDGClientForwarder) accesslist() string {
if f.Config().AccessListType != "" && len(f.Config().AccessList) > 0 {
r := ""
for _, s := range f.accessList {
for _, s := range f.Config().AccessList {
r += s + ","
}
return "i2cp.accessList=" + strings.TrimSuffix(r, ",")
@ -191,52 +134,52 @@ func (f *SAMSSUClientForwarder) accesslist() string {
return ""
}
func (f *SAMSSUClientForwarder) leasesetsettings() (string, string, string) {
func (f *SAMDGClientForwarder) leasesetsettings() (string, string, string) {
var r, s, t string
if f.leaseSetKey != "" {
r = "i2cp.leaseSetKey=" + f.leaseSetKey
if f.Config().LeaseSetKey != "" {
r = "i2cp.leaseSetKey=" + f.Config().LeaseSetKey
}
if f.leaseSetPrivateKey != "" {
s = "i2cp.leaseSetPrivateKey=" + f.leaseSetPrivateKey
if f.Config().LeaseSetPrivateKey != "" {
s = "i2cp.leaseSetPrivateKey=" + f.Config().LeaseSetPrivateKey
}
if f.leaseSetPrivateSigningKey != "" {
t = "i2cp.leaseSetPrivateSigningKey=" + f.leaseSetPrivateSigningKey
if f.Config().LeaseSetPrivateSigningKey != "" {
t = "i2cp.leaseSetPrivateSigningKey=" + f.Config().LeaseSetPrivateSigningKey
}
return r, s, t
}
// Destination returns the destination of the i2p service you want to forward locally
func (f *SAMSSUClientForwarder) Destination() string {
func (f *SAMDGClientForwarder) Destination() string {
return f.addr.Base32()
}
// Target returns the host:port of the local service you want to forward to i2p
func (f *SAMSSUClientForwarder) Target() string {
return f.TargetHost + ":" + f.TargetPort
func (f *SAMDGClientForwarder) Target() string {
return f.Config().TargetHost + ":" + f.Config().TargetPort
}
func (f *SAMSSUClientForwarder) sam() string {
return f.SamHost + ":" + f.SamPort
func (f *SAMDGClientForwarder) sam() string {
return f.Config().SamHost + ":" + f.Config().SamPort
}
//Base32 returns the base32 address of the local destination
func (f *SAMSSUClientForwarder) Base32() string {
func (f *SAMDGClientForwarder) Base32() string {
return f.SamKeys.Addr().Base32()
}
//Base32Readable returns the base32 address where the local service is being forwarded
func (f *SAMSSUClientForwarder) Base32Readable() string {
func (f *SAMDGClientForwarder) Base32Readable() string {
b32 := strings.Replace(f.Base32(), ".b32.i2p", "", 1)
rhash, _ := f.Hasher.Friendly(b32)
return rhash + " " + strconv.Itoa(len(b32))
}
//Base64 returns the base64 address of the local destination
func (f *SAMSSUClientForwarder) Base64() string {
func (f *SAMDGClientForwarder) Base64() string {
return f.SamKeys.Addr().Base64()
}
func (f *SAMSSUClientForwarder) forward(conn net.PacketConn) {
func (f *SAMDGClientForwarder) forward(conn net.PacketConn) {
// go func() {
// defer f.connectStream.Close()
// defer f.publishConnection.Close()
@ -261,11 +204,11 @@ func (f *SAMSSUClientForwarder) forward(conn net.PacketConn) {
// }()
}
func (f *SAMSSUClientForwarder) Up() bool {
func (f *SAMDGClientForwarder) Up() bool {
return f.up
}
func (f *SAMSSUClientForwarder) errSleep(err error) bool {
func (f *SAMDGClientForwarder) errSleep(err error) bool {
if err != nil {
log.Printf("Dial failed: %v, waiting 5 minutes to try again\n", err)
time.Sleep(5 * time.Minute)
@ -276,16 +219,16 @@ func (f *SAMSSUClientForwarder) errSleep(err error) bool {
}
//Serve starts the SAM connection and and forwards the local host:port to i2p
func (f *SAMSSUClientForwarder) Serve() error {
func (f *SAMDGClientForwarder) Serve() error {
var err error
log.Println("Establishing a SAM datagram session.")
if f.publishConnection, err = net.ListenPacket("udp", f.Target()); err != nil {
return err
if f.publishConnection, err = net.ListenPacket("udp", f.Config().Target()); err != nil {
return fmt.Errorf("Listener creation Error%s", err)
}
//p, _ := strconv.Atoi(f.TargetPort)
sp, _ := strconv.Atoi(f.SamPort)
//p, _ := strconv.Atoi(f.Config().TargetPort)
sp, _ := strconv.Atoi(f.Config().SamPort)
f.connectStream, err = f.samConn.NewDatagramSession(
f.TunName,
f.Config().TunName,
f.SamKeys,
f.print(),
sp-1,
@ -298,7 +241,7 @@ func (f *SAMSSUClientForwarder) Serve() error {
log.Println("Human-readable hash of Client:\n ", f.Base32Readable())
/* Close := false
for !Close {
//addr, err := net.ResolveUDPAddr("udp", f.Target())
//addr, err := net.ResolveUDPAddr("udp", f.Config().Target())
Close = f.errSleep(err)
//f.publishConnection, err = net.DialUDP("udp", nil, addr)
Close = f.errSleep(err)
@ -310,79 +253,53 @@ func (f *SAMSSUClientForwarder) Serve() error {
return nil
}
func (s *SAMSSUClientForwarder) Load() (samtunnel.SAMTunnel, error) {
func (s *SAMDGClientForwarder) Load() (samtunnel.SAMTunnel, error) {
if s.samConn, err = sam3.NewSAM(s.sam()); err != nil {
return nil, err
return nil, fmt.Errorf("SAM connection error %s", err)
}
if s.addr, err = s.samConn.Lookup(s.dest); err != nil {
return nil, err
if s.addr, err = s.samConn.Lookup(s.Config().ClientDest); err != nil {
return nil, fmt.Errorf("%s", err)
}
log.Println("SAM Bridge connection established.")
if s.save {
if s.Config().SaveFile {
log.Println("Saving i2p keys")
}
if s.SamKeys, err = sfi2pkeys.Load(s.FilePath, s.TunName, s.passfile, s.samConn, s.save); err != nil {
return nil, err
if s.SamKeys, err = sfi2pkeys.Load(s.Config().FilePath, s.Config().TunName, s.Config().KeyFilePath, s.samConn, s.Config().SaveFile); err != nil {
return nil, fmt.Errorf("I2P key load/generate error%s", err)
}
log.Println("Destination keys generated, tunnel name:", s.TunName)
if s.save {
if err := sfi2pkeys.Save(s.FilePath, s.TunName, s.passfile, s.SamKeys); err != nil {
return nil, err
log.Println("Destination keys generated, tunnel name:", s.Config().TunName)
if s.Config().SaveFile {
if err := sfi2pkeys.Save(s.Config().FilePath, s.Config().TunName, s.Config().KeyFilePath, s.SamKeys); err != nil {
return nil, fmt.Errorf("I2P key storage error %s", err)
}
log.Println("Saved tunnel keys for", s.TunName)
log.Println("Saved tunnel keys for", s.Conf.TunName, "in", s.Conf.FilePath)
}
s.Hasher, err = hashhash.NewHasher(len(strings.Replace(s.Base32(), ".b32.i2p", "", 1)))
if err != nil {
return nil, err
return nil, fmt.Errorf("Human-readable hasher error %s", err)
}
s.up = true
return s, nil
}
//NewSAMSSUClientForwarderFromOptions makes a new SAM forwarder with default options, accepts host:port arguments
func NewSAMSSUClientForwarderFromOptions(opts ...func(*SAMSSUClientForwarder) error) (*SAMSSUClientForwarder, error) {
var s SAMSSUClientForwarder
s.SamHost = "127.0.0.1"
s.SamPort = "7656"
s.FilePath = ""
s.save = false
s.TargetHost = "127.0.0.1"
s.TargetPort = "0"
s.TunName = "samSSUForwarder"
s.inLength = "3"
s.outLength = "3"
s.inQuantity = "2"
s.outQuantity = "2"
s.inVariance = "1"
s.outVariance = "1"
s.inBackupQuantity = "3"
s.outBackupQuantity = "3"
s.inAllowZeroHop = "false"
s.outAllowZeroHop = "false"
s.fastRecieve = "false"
s.useCompression = "true"
s.encryptLeaseSet = "false"
s.leaseSetKey = ""
s.leaseSetPrivateKey = ""
s.leaseSetPrivateSigningKey = ""
s.reduceIdle = "false"
s.reduceIdleTime = "15"
s.closeIdle = "false"
s.closeIdleTime = "30"
s.reduceIdleQuantity = "4"
s.dest = "none"
s.Type = "udpclient"
s.messageReliability = "none"
s.passfile = ""
s.dest = "i2p-projekt.i2p"
//NewSAMDGForwarder makes a new SAM forwarder with default options, accepts host:port arguments
func NewSAMDGClientForwarder(host, port string) (samtunnel.SAMTunnel, error) {
return NewSAMDGClientForwarderFromOptions(samoptions.SetHost(host), samoptions.SetPort(port))
}
//NewSAMDGClientForwarderFromOptions makes a new SAM forwarder with default options, accepts host:port arguments
func NewSAMDGClientForwarderFromOptions(opts ...func(samtunnel.SAMTunnel) error) (*SAMDGClientForwarder, error) {
var s SAMDGClientForwarder
s.Conf = i2ptunconf.NewI2PBlankTunConf()
s.Conf.Type = "udpclient"
for _, o := range opts {
if err := o(&s); err != nil {
return nil, err
return nil, fmt.Errorf("Option setting error %s", err)
}
}
l, e := s.Load()
if e != nil {
return nil, e
return nil, fmt.Errorf("Tunnel loading error %s", e)
}
return l.(*SAMSSUClientForwarder), nil
return l.(*SAMDGClientForwarder), nil
}

View File

@ -1,405 +0,0 @@
package samforwarderudp
import (
"fmt"
"strconv"
)
//Option is a SAMSSUForwarder Option
type Option func(*SAMSSUForwarder) error
//SetFilePath sets the host of the SAMSSUForwarder's SAM bridge
func SetFilePath(s string) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
c.FilePath = s
return nil
}
}
//SetSaveFile tells the router to use an encrypted leaseset
func SetSaveFile(b bool) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
c.save = b
return nil
}
}
//SetHost sets the host of the SAMSSUForwarder's SAM bridge
func SetHost(s string) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
c.TargetHost = s
return nil
}
}
//SetPort sets the port of the SAMSSUForwarder's SAM bridge using a string
func SetPort(s string) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
port, err := strconv.Atoi(s)
if err != nil {
return fmt.Errorf("Invalid SSU Server Target Port %s; non-number ", s)
}
if port < 65536 && port > -1 {
c.TargetPort = s
return nil
}
return fmt.Errorf("Invalid port")
}
}
//SetSAMHost sets the host of the SAMSSUForwarder's SAM bridge
func SetSAMHost(s string) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
c.SamHost = s
return nil
}
}
//SetSAMPort sets the port of the SAMSSUForwarder's SAM bridge using a string
func SetSAMPort(s string) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
port, err := strconv.Atoi(s)
if err != nil {
return fmt.Errorf("Invalid SAM Port %s; non-number", s)
}
if port < 65536 && port > -1 {
c.SamPort = s
return nil
}
return fmt.Errorf("Invalid port")
}
}
//SetName sets the host of the SAMSSUForwarder's SAM bridge
func SetName(s string) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
c.TunName = s
return nil
}
}
//SetSigType sets the type of the forwarder server
func SetSigType(s string) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
if s == "" {
c.sigType = ""
} else if s == "DSA_SHA1" {
c.sigType = "DSA_SHA1"
} else if s == "ECDSA_SHA256_P256" {
c.sigType = "ECDSA_SHA256_P256"
} else if s == "ECDSA_SHA384_P384" {
c.sigType = "ECDSA_SHA384_P384"
} else if s == "ECDSA_SHA512_P521" {
c.sigType = "ECDSA_SHA512_P521"
} else if s == "EdDSA_SHA512_Ed25519" {
c.sigType = "EdDSA_SHA512_Ed25519"
} else {
c.sigType = "EdDSA_SHA512_Ed25519"
}
return nil
}
}
//SetInLength sets the number of hops inbound
func SetInLength(u int) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
if u < 7 && u >= 0 {
c.inLength = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid inbound tunnel length")
}
}
//SetOutLength sets the number of hops outbound
func SetOutLength(u int) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
if u < 7 && u >= 0 {
c.outLength = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid outbound tunnel length")
}
}
//SetInVariance sets the variance of a number of hops inbound
func SetInVariance(i int) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
if i < 7 && i > -7 {
c.inVariance = strconv.Itoa(i)
return nil
}
return fmt.Errorf("Invalid inbound tunnel length")
}
}
//SetOutVariance sets the variance of a number of hops outbound
func SetOutVariance(i int) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
if i < 7 && i > -7 {
c.outVariance = strconv.Itoa(i)
return nil
}
return fmt.Errorf("Invalid outbound tunnel variance")
}
}
//SetInQuantity sets the inbound tunnel quantity
func SetInQuantity(u int) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
if u <= 16 && u > 0 {
c.inQuantity = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid inbound tunnel quantity")
}
}
//SetOutQuantity sets the outbound tunnel quantity
func SetOutQuantity(u int) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
if u <= 16 && u > 0 {
c.outQuantity = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid outbound tunnel quantity")
}
}
//SetInBackups sets the inbound tunnel backups
func SetInBackups(u int) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
if u < 6 && u >= 0 {
c.inBackupQuantity = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid inbound tunnel backup quantity")
}
}
//SetOutBackups sets the inbound tunnel backups
func SetOutBackups(u int) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
if u < 6 && u >= 0 {
c.outBackupQuantity = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid outbound tunnel backup quantity")
}
}
//SetEncrypt tells the router to use an encrypted leaseset
func SetEncrypt(b bool) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
if b {
c.encryptLeaseSet = "true"
return nil
}
c.encryptLeaseSet = "false"
return nil
}
}
//SetLeaseSetKey sets
func SetLeaseSetKey(s string) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
c.leaseSetKey = s
return nil
}
}
//SetLeaseSetPrivateKey sets
func SetLeaseSetPrivateKey(s string) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
c.leaseSetPrivateKey = s
return nil
}
}
//SetLeaseSetPrivateSigningKey sets
func SetLeaseSetPrivateSigningKey(s string) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
c.leaseSetPrivateSigningKey = s
return nil
}
}
//SetMessageReliability sets
func SetMessageReliability(s string) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
c.messageReliability = s
return nil
}
}
//SetAllowZeroIn tells the tunnel to accept zero-hop peers
func SetAllowZeroIn(b bool) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
if b {
c.inAllowZeroHop = "true"
return nil
}
c.inAllowZeroHop = "false"
return nil
}
}
//SetAllowZeroOut tells the tunnel to accept zero-hop peers
func SetAllowZeroOut(b bool) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
if b {
c.outAllowZeroHop = "true"
return nil
}
c.outAllowZeroHop = "false"
return nil
}
}
//SetFastRecieve tells clients to use compression
func SetFastRecieve(b bool) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
if b {
c.fastRecieve = "true"
return nil
}
c.fastRecieve = "false"
return nil
}
}
//SetCompress tells clients to use compression
func SetCompress(b bool) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
if b {
c.useCompression = "true"
return nil
}
c.useCompression = "false"
return nil
}
}
//SetReduceIdle tells the connection to reduce it's tunnels during extended idle time.
func SetReduceIdle(b bool) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
if b {
c.reduceIdle = "true"
return nil
}
c.reduceIdle = "false"
return nil
}
}
//SetReduceIdleTime sets the time to wait before reducing tunnels to idle levels
func SetReduceIdleTime(u int) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
c.reduceIdleTime = "300000"
if u >= 6 {
c.reduceIdleTime = strconv.Itoa((u * 60) * 1000)
return nil
}
return fmt.Errorf("Invalid close idle timeout(Measured in minutes) %v", u)
}
}
//SetReduceIdleTimeMs sets the time to wait before reducing tunnels to idle levels in milliseconds
func SetReduceIdleTimeMs(u int) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
c.reduceIdleTime = "300000"
if u >= 300000 {
c.reduceIdleTime = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid close idle timeout(Measured in milliseconds) %v", u)
}
}
//SetReduceIdleQuantity sets minimum number of tunnels to reduce to during idle time
func SetReduceIdleQuantity(u int) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
if u < 5 {
c.reduceIdleQuantity = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid reduce tunnel quantity")
}
}
//SetCloseIdle tells the connection to close it's tunnels during extended idle time.
func SetCloseIdle(b bool) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
if b {
c.closeIdle = "true"
return nil
}
c.closeIdle = "false"
return nil
}
}
//SetCloseIdleTime sets the time to wait before closing tunnels to idle levels
func SetCloseIdleTime(u int) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
c.closeIdleTime = "300000"
if u >= 6 {
c.closeIdleTime = strconv.Itoa((u * 60) * 2000)
return nil
}
return fmt.Errorf("Invalid reduce idle timeout(Measured in minutes)")
}
}
//SetCloseIdleTimeMs sets the time to wait before closing tunnels to idle levels in milliseconds
func SetCloseIdleTimeMs(u int) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
c.closeIdleTime = "300000"
if u >= 300000 {
c.closeIdleTime = strconv.Itoa(u)
return nil
}
return fmt.Errorf("Invalid reduce idle timeout(Measured in minutes)")
}
}
//SetAccessListType tells the system to treat the accessList as a whitelist
func SetAccessListType(s string) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
if s == "whitelist" {
c.accessListType = "whitelist"
return nil
} else if s == "blacklist" {
c.accessListType = "blacklist"
return nil
} else if s == "none" {
c.accessListType = ""
return nil
} else if s == "" {
c.accessListType = ""
return nil
}
return fmt.Errorf("Invalid Access list type(whitelist, blacklist, none)")
}
}
//SetAccessList tells the system to treat the accessList as a whitelist
func SetAccessList(s []string) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
if len(s) > 0 {
for _, a := range s {
c.accessList = append(c.accessList, a)
}
return nil
}
return nil
}
}
//SetKeyFile sets
func SetKeyFile(s string) func(*SAMSSUForwarder) error {
return func(c *SAMSSUForwarder) error {
c.passfile = s
return nil
}
}

View File

@ -1,105 +1,74 @@
package samforwarderudp
import (
"fmt"
"io"
"log"
"net"
//"os"
//"path/filepath"
"strconv"
"strings"
"time"
)
import (
"github.com/eyedeekay/sam-forwarder/config"
"github.com/eyedeekay/sam-forwarder/hashhash"
"github.com/eyedeekay/sam-forwarder/i2pkeys"
"github.com/eyedeekay/sam-forwarder/interface"
"github.com/eyedeekay/sam-forwarder/options"
"github.com/eyedeekay/sam3"
"github.com/eyedeekay/sam3/i2pkeys"
)
//SAMSSUForwarder is a structure which automatically configured the forwarding of
//SAMDGForwarder is a structure which automatically configured the forwarding of
//a local service to i2p over the SAM API.
type SAMSSUForwarder struct {
SamHost string
SamPort string
TunName string
Type string
TargetHost string
TargetPort string
type SAMDGForwarder struct {
samConn *sam3.SAM
SamKeys i2pkeys.I2PKeys
Hasher *hashhash.Hasher
publishConnection *sam3.DatagramSession
clientConnection net.PacketConn
FilePath string
file io.ReadWriter
save bool
up bool
file io.ReadWriter
up bool
// samcatd options
passfile string
sigType string
// I2CP options
encryptLeaseSet string
leaseSetKey string
leaseSetPrivateKey string
leaseSetPrivateSigningKey string
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
//Streaming Library options
accessListType string
accessList []string
// config
Conf *i2ptunconf.Conf
}
var err error
func (f *SAMSSUForwarder) GetType() string {
return f.Type
func (f *SAMDGForwarder) Config() *i2ptunconf.Conf {
if f.Conf == nil {
f.Conf = i2ptunconf.NewI2PBlankTunConf()
}
return f.Conf
}
func (f *SAMSSUForwarder) ID() string {
return f.TunName
func (f *SAMDGForwarder) GetType() string {
return f.Config().Type
}
func (f *SAMSSUForwarder) Keys() i2pkeys.I2PKeys {
func (f *SAMDGForwarder) ID() string {
return f.Config().TunName
}
func (f *SAMDGForwarder) Keys() i2pkeys.I2PKeys {
return f.SamKeys
}
func (f *SAMSSUForwarder) Cleanup() {
func (f *SAMDGForwarder) Cleanup() {
f.publishConnection.Close()
f.clientConnection.Close()
f.samConn.Close()
}
func (f *SAMSSUForwarder) Close() error {
func (f *SAMDGForwarder) Close() error {
return nil
}
func (f *SAMSSUForwarder) print() []string {
lsk, lspk, lspsk := f.leasesetsettings()
func (f *SAMDGForwarder) print() []string {
/*lsk, lspk, lspsk := f.leasesetsettings()
return []string{
//f.targetForPort443(),
"inbound.length=" + f.inLength,
@ -124,10 +93,11 @@ func (f *SAMSSUForwarder) print() []string {
lsk, lspk, lspsk,
f.accesslisttype(),
f.accesslist(),
}
}*/
return f.Config().PrintSlice()
}
func (f *SAMSSUForwarder) Props() map[string]string {
func (f *SAMDGForwarder) Props() map[string]string {
r := make(map[string]string)
print := f.print()
print = append(print, "base32="+f.Base32())
@ -140,10 +110,10 @@ func (f *SAMSSUForwarder) Props() map[string]string {
return r
}
func (f *SAMSSUForwarder) Print() string {
func (f *SAMDGForwarder) Print() string {
var r string
r += "name=" + f.TunName + "\n"
r += "type=" + f.Type + "\n"
r += "name=" + f.Config().TunName + "\n"
r += "type=" + f.Config().Type + "\n"
r += "base32=" + f.Base32() + "\n"
r += "base64=" + f.Base64() + "\n"
r += "ssuserver\n"
@ -153,7 +123,7 @@ func (f *SAMSSUForwarder) Print() string {
return strings.Replace(r, "\n\n", "\n", -1)
}
func (f *SAMSSUForwarder) Search(search string) string {
func (f *SAMDGForwarder) Search(search string) string {
terms := strings.Split(search, ",")
if search == "" {
return f.Print()
@ -166,21 +136,21 @@ func (f *SAMSSUForwarder) Search(search string) string {
return f.Print()
}
func (f *SAMSSUForwarder) accesslisttype() string {
if f.accessListType == "whitelist" {
func (f *SAMDGForwarder) accesslisttype() string {
if f.Config().AccessListType == "allowlist" {
return "i2cp.enableAccessList=true"
} else if f.accessListType == "blacklist" {
} else if f.Config().AccessListType == "blocklist" {
return "i2cp.enableBlackList=true"
} else if f.accessListType == "none" {
} else if f.Config().AccessListType == "none" {
return ""
}
return ""
}
func (f *SAMSSUForwarder) accesslist() string {
if f.accessListType != "" && len(f.accessList) > 0 {
func (f *SAMDGForwarder) accesslist() string {
if f.Config().AccessListType != "" && len(f.Config().AccessList) > 0 {
r := ""
for _, s := range f.accessList {
for _, s := range f.Config().AccessList {
r += s + ","
}
return "i2cp.accessList=" + strings.TrimSuffix(r, ",")
@ -188,38 +158,38 @@ func (f *SAMSSUForwarder) accesslist() string {
return ""
}
func (f *SAMSSUForwarder) leasesetsettings() (string, string, string) {
func (f *SAMDGForwarder) leasesetsettings() (string, string, string) {
var r, s, t string
if f.leaseSetKey != "" {
r = "i2cp.leaseSetKey=" + f.leaseSetKey
if f.Config().LeaseSetKey != "" {
r = "i2cp.leaseSetKey=" + f.Config().LeaseSetKey
}
if f.leaseSetPrivateKey != "" {
s = "i2cp.leaseSetPrivateKey=" + f.leaseSetPrivateKey
if f.Config().LeaseSetPrivateKey != "" {
s = "i2cp.leaseSetPrivateKey=" + f.Config().LeaseSetPrivateKey
}
if f.leaseSetPrivateSigningKey != "" {
t = "i2cp.leaseSetPrivateSigningKey=" + f.leaseSetPrivateSigningKey
if f.Config().LeaseSetPrivateSigningKey != "" {
t = "i2cp.leaseSetPrivateSigningKey=" + f.Config().LeaseSetPrivateSigningKey
}
return r, s, t
}
// Target returns the host:port of the local service you want to forward to i2p
func (f *SAMSSUForwarder) Target() string {
return f.TargetHost + ":" + f.TargetPort
func (f *SAMDGForwarder) Target() string {
return f.Config().TargetHost + ":" + f.Config().TargetPort
}
func (f *SAMSSUForwarder) sam() string {
return f.SamHost + ":" + f.SamPort
func (f *SAMDGForwarder) sam() string {
return f.Config().SamHost + ":" + f.Config().SamPort
}
//func (f *SAMSSUForwarder) forward(conn net.Conn) {
func (f *SAMSSUForwarder) forward() {
//func (f *SAMDGForwarder) forward(conn net.Conn) {
func (f *SAMDGForwarder) forward() {
Loop := false
if f.clientConnection == nil {
for !Loop {
log.Println("Attempting to resolve local UDP Service to forward to I2P", f.Target())
addr, err := net.ResolveUDPAddr("udp", f.Target())
log.Println("Attempting to resolve local UDP Service to forward to I2P", f.Config().Target())
addr, err := net.ResolveUDPAddr("udp", f.Config().Target())
Loop = f.errSleep(err)
log.Println("Attempting to dial resolved UDP Address", f.Target())
log.Println("Attempting to dial resolved UDP Address", f.Config().Target())
f.clientConnection, err = net.DialUDP("udp", nil, addr)
Loop = f.errSleep(err)
log.Printf("Connected %v to localhost %v\n", f.publishConnection, f.clientConnection)
@ -249,23 +219,23 @@ func (f *SAMSSUForwarder) forward() {
}
//Base32 returns the base32 address where the local service is being forwarded
func (f *SAMSSUForwarder) Base32() string {
func (f *SAMDGForwarder) Base32() string {
return f.SamKeys.Addr().Base32()
}
//Base32Readable returns the base32 address where the local service is being forwarded
func (f *SAMSSUForwarder) Base32Readable() string {
func (f *SAMDGForwarder) Base32Readable() string {
b32 := strings.Replace(f.Base32(), ".b32.i2p", "", 1)
rhash, _ := f.Hasher.Friendly(b32)
return rhash + " " + strconv.Itoa(len(b32))
}
//Base64 returns the base64 address where the local service is being forwarded
func (f *SAMSSUForwarder) Base64() string {
func (f *SAMDGForwarder) Base64() string {
return f.SamKeys.Addr().Base64()
}
func (f *SAMSSUForwarder) errSleep(err error) bool {
func (f *SAMDGForwarder) errSleep(err error) bool {
if err != nil {
log.Printf("Dial failed: %v, waiting 5 minutes to try again\n", err)
time.Sleep(5 * time.Minute)
@ -276,19 +246,18 @@ func (f *SAMSSUForwarder) errSleep(err error) bool {
}
//Serve starts the SAM connection and and forwards the local host:port to i2p
func (f *SAMSSUForwarder) Serve() error {
func (f *SAMDGForwarder) Serve() error {
var err error
sp, _ := strconv.Atoi(f.SamPort)
sp, err := strconv.Atoi(f.Config().SamPort)
f.publishConnection, err = f.samConn.NewDatagramSession(
f.TunName,
f.Config().TunName,
f.SamKeys,
f.print(),
sp-1,
)
if err != nil {
log.Println("Session Creation error:", err.Error())
return err
return fmt.Errorf("Session creation Error%s", err)
}
log.Println("SAM datagram session established.")
@ -300,84 +269,55 @@ func (f *SAMSSUForwarder) Serve() error {
}
}
func (s *SAMSSUForwarder) Load() (samtunnel.SAMTunnel, error) {
func (s *SAMDGForwarder) Load() (samtunnel.SAMTunnel, error) {
s.samConn, err = sam3.NewSAM(s.sam())
if err != nil {
return nil, err
return nil, fmt.Errorf("SAM connection error%s", err)
}
log.Println("SAM Bridge connection established.")
if s.save {
if s.Config().SaveFile {
log.Println("Saving i2p keys")
}
if s.SamKeys, err = sfi2pkeys.Load(s.FilePath, s.TunName, s.passfile, s.samConn, s.save); err != nil {
return nil, err
if s.SamKeys, err = sfi2pkeys.Load(s.Config().FilePath, s.Config().TunName, s.Config().KeyFilePath, s.samConn, s.Config().SaveFile); err != nil {
return nil, fmt.Errorf("SAM key load/generate error%s", err)
}
log.Println("Destination keys generated, tunnel name:", s.TunName)
if s.save {
if err := sfi2pkeys.Save(s.FilePath, s.TunName, s.passfile, s.SamKeys); err != nil {
return nil, err
log.Println("Destination keys generated, tunnel name:", s.Config().TunName)
if s.Config().SaveFile {
if err := sfi2pkeys.Save(s.Config().FilePath, s.Config().TunName, s.Config().KeyFilePath, s.SamKeys); err != nil {
return nil, fmt.Errorf("SAM key save error%s", err)
}
log.Println("Saved tunnel keys for", s.TunName)
log.Println("Saved tunnel keys for", s.Conf.TunName, "in", s.Conf.FilePath)
}
s.Hasher, err = hashhash.NewHasher(len(strings.Replace(s.Base32(), ".b32.i2p", "", 1)))
if err != nil {
return nil, err
return nil, fmt.Errorf("Word-hash generation error%s", err)
}
s.up = true
return s, nil
}
func (f *SAMSSUForwarder) Up() bool {
func (f *SAMDGForwarder) Up() bool {
return f.up
}
//NewSAMSSUForwarder makes a new SAM forwarder with default options, accepts host:port arguments
func NewSAMSSUForwarder(host, port string) (*SAMSSUForwarder, error) {
return NewSAMSSUForwarderFromOptions(SetHost(host), SetPort(port))
//NewSAMDGForwarder makes a new SAM forwarder with default options, accepts host:port arguments
func NewSAMDGForwarder(host, port string) (samtunnel.SAMTunnel, error) {
return NewSAMDGForwarderFromOptions(samoptions.SetHost(host), samoptions.SetPort(port))
}
//NewSAMSSUForwarderFromOptions makes a new SAM forwarder with default options, accepts host:port arguments
func NewSAMSSUForwarderFromOptions(opts ...func(*SAMSSUForwarder) error) (*SAMSSUForwarder, error) {
var s SAMSSUForwarder
s.SamHost = "127.0.0.1"
s.SamPort = "7656"
s.FilePath = ""
s.save = false
s.TargetHost = "127.0.0.1"
s.TargetPort = "8081"
s.TunName = "samSSUForwarder"
s.inLength = "3"
s.outLength = "3"
s.inQuantity = "2"
s.outQuantity = "2"
s.inVariance = "1"
s.outVariance = "1"
s.inBackupQuantity = "3"
s.outBackupQuantity = "3"
s.inAllowZeroHop = "false"
s.outAllowZeroHop = "false"
s.fastRecieve = "false"
s.useCompression = "true"
s.encryptLeaseSet = "false"
s.leaseSetKey = ""
s.leaseSetPrivateKey = ""
s.leaseSetPrivateSigningKey = ""
s.reduceIdle = "false"
s.reduceIdleTime = "300000"
s.closeIdle = "false"
s.closeIdleTime = "300000"
s.reduceIdleQuantity = "4"
s.Type = "udpserver"
s.messageReliability = "none"
s.passfile = ""
//NewSAMDGForwarderFromOptions makes a new SAM forwarder with default options, accepts host:port arguments
func NewSAMDGForwarderFromOptions(opts ...func(samtunnel.SAMTunnel) error) (*SAMDGForwarder, error) {
var s SAMDGForwarder
s.Conf = i2ptunconf.NewI2PBlankTunConf()
s.Conf.Type = "udpserver"
for _, o := range opts {
if err := o(&s); err != nil {
return nil, err
return nil, fmt.Errorf("Option Setting Error: %s", err)
}
}
l, e := s.Load()
if e != nil {
return nil, e
return nil, fmt.Errorf("%s", e)
}
return l.(*SAMSSUForwarder), nil
return l.(*SAMDGForwarder), nil
}

View File

@ -3,114 +3,116 @@ package samforwarderudp
import (
"log"
"testing"
"github.com/eyedeekay/sam-forwarder/options"
)
func TestOptionUDPHost(t *testing.T) {
client, err := NewSAMSSUForwarderFromOptions(SetHost("127.0.0.1"))
client, err := NewSAMDGForwarderFromOptions(samoptions.SetHost("127.0.0.1"))
if err != nil {
t.Fatalf("NewSAMSSUForwarder() Error: %q\n", err)
t.Fatalf("NewSAMDGForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionUDPPort(t *testing.T) {
client, err := NewSAMSSUForwarderFromOptions(SetPort("7656"))
client, err := NewSAMDGForwarderFromOptions(samoptions.SetPort("7656"))
if err != nil {
t.Fatalf("NewSAMSSUForwarder() Error: %q\n", err)
t.Fatalf("NewSAMDGForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionUDPInLength(t *testing.T) {
client, err := NewSAMSSUForwarderFromOptions(SetInLength(3))
client, err := NewSAMDGForwarderFromOptions(samoptions.SetInLength(3))
if err != nil {
t.Fatalf("NewSAMSSUForwarder() Error: %q\n", err)
t.Fatalf("NewSAMDGForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionUDPOutLength(t *testing.T) {
client, err := NewSAMSSUForwarderFromOptions(SetInLength(3))
client, err := NewSAMDGForwarderFromOptions(samoptions.SetInLength(3))
if err != nil {
t.Fatalf("NewSAMSSUForwarder() Error: %q\n", err)
t.Fatalf("NewSAMDGForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionUDPInVariance(t *testing.T) {
client, err := NewSAMSSUForwarderFromOptions(SetInVariance(1))
client, err := NewSAMDGForwarderFromOptions(samoptions.SetInVariance(1))
if err != nil {
t.Fatalf("NewSAMSSUForwarder() Error: %q\n", err)
t.Fatalf("NewSAMDGForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionUDPOutVariance(t *testing.T) {
client, err := NewSAMSSUForwarderFromOptions(SetOutVariance(1))
client, err := NewSAMDGForwarderFromOptions(samoptions.SetOutVariance(1))
if err != nil {
t.Fatalf("NewSAMSSUForwarder() Error: %q\n", err)
t.Fatalf("NewSAMDGForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionUDPInQuantity(t *testing.T) {
client, err := NewSAMSSUForwarderFromOptions(SetInQuantity(6))
client, err := NewSAMDGForwarderFromOptions(samoptions.SetInQuantity(6))
if err != nil {
t.Fatalf("NewSAMSSUForwarder() Error: %q\n", err)
t.Fatalf("NewSAMDGForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionUDPOutQuantity(t *testing.T) {
client, err := NewSAMSSUForwarderFromOptions(SetOutQuantity(6))
client, err := NewSAMDGForwarderFromOptions(samoptions.SetOutQuantity(6))
if err != nil {
t.Fatalf("NewSAMSSUForwarder() Error: %q\n", err)
t.Fatalf("NewSAMDGForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionUDPInBackups(t *testing.T) {
client, err := NewSAMSSUForwarderFromOptions(SetInBackups(5))
client, err := NewSAMDGForwarderFromOptions(samoptions.SetInBackups(5))
if err != nil {
t.Fatalf("NewSAMSSUForwarder() Error: %q\n", err)
t.Fatalf("NewSAMDGForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionUDPOutBackups(t *testing.T) {
client, err := NewSAMSSUForwarderFromOptions(SetOutBackups(5))
client, err := NewSAMDGForwarderFromOptions(samoptions.SetOutBackups(5))
if err != nil {
t.Fatalf("NewSAMSSUForwarder() Error: %q\n", err)
t.Fatalf("NewSAMDGForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionUDPReduceIdleQuantity(t *testing.T) {
client, err := NewSAMSSUForwarderFromOptions(SetReduceIdleQuantity(4))
client, err := NewSAMDGForwarderFromOptions(samoptions.SetReduceIdleQuantity(4))
if err != nil {
t.Fatalf("NewSAMSSUForwarder() Error: %q\n", err)
t.Fatalf("NewSAMDGForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionUDPEncryptLease(t *testing.T) {
client, err := NewSAMSSUForwarderFromOptions(SetEncrypt(true))
client, err := NewSAMDGForwarderFromOptions(samoptions.SetEncrypt(true))
if err != nil {
t.Fatalf("NewSAMSSUForwarder() Error: %q\n", err)
t.Fatalf("NewSAMDGForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionUDPSaveFile(t *testing.T) {
client, err := NewSAMSSUForwarderFromOptions(SetSaveFile(true))
client, err := NewSAMDGForwarderFromOptions(samoptions.SetSaveFile(true))
if err != nil {
t.Fatalf("NewSAMSSUForwarder() Error: %q\n", err)
t.Fatalf("NewSAMDGForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestClientOptionHost(t *testing.T) {
client, err := NewSAMSSUClientForwarderFromOptions(SetClientHost("127.0.0.1"))
client, err := NewSAMDGClientForwarderFromOptions(samoptions.SetHost("127.0.0.1"))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -118,7 +120,7 @@ func TestClientOptionHost(t *testing.T) {
}
func TestClientOptionPort(t *testing.T) {
client, err := NewSAMSSUClientForwarderFromOptions(SetClientSAMPort("7656"))
client, err := NewSAMDGClientForwarderFromOptions(samoptions.SetSAMPort("7656"))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -126,7 +128,7 @@ func TestClientOptionPort(t *testing.T) {
}
func TestClientOptionInLength(t *testing.T) {
client, err := NewSAMSSUClientForwarderFromOptions(SetClientInLength(3))
client, err := NewSAMDGClientForwarderFromOptions(samoptions.SetInLength(3))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -134,7 +136,7 @@ func TestClientOptionInLength(t *testing.T) {
}
func TestClientOptionOutLength(t *testing.T) {
client, err := NewSAMSSUClientForwarderFromOptions(SetClientInLength(3))
client, err := NewSAMDGClientForwarderFromOptions(samoptions.SetInLength(3))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -142,7 +144,7 @@ func TestClientOptionOutLength(t *testing.T) {
}
func TestClientOptionInVariance(t *testing.T) {
client, err := NewSAMSSUClientForwarderFromOptions(SetClientInVariance(1))
client, err := NewSAMDGClientForwarderFromOptions(samoptions.SetInVariance(1))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -150,7 +152,7 @@ func TestClientOptionInVariance(t *testing.T) {
}
func TestClientOptionOutVariance(t *testing.T) {
client, err := NewSAMSSUClientForwarderFromOptions(SetClientOutVariance(1))
client, err := NewSAMDGClientForwarderFromOptions(samoptions.SetOutVariance(1))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -158,7 +160,7 @@ func TestClientOptionOutVariance(t *testing.T) {
}
func TestClientOptionInQuantity(t *testing.T) {
client, err := NewSAMSSUClientForwarderFromOptions(SetClientInQuantity(6))
client, err := NewSAMDGClientForwarderFromOptions(samoptions.SetInQuantity(6))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -166,7 +168,7 @@ func TestClientOptionInQuantity(t *testing.T) {
}
func TestClientOptionOutQuantity(t *testing.T) {
client, err := NewSAMSSUClientForwarderFromOptions(SetClientOutQuantity(6))
client, err := NewSAMDGClientForwarderFromOptions(samoptions.SetOutQuantity(6))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -174,7 +176,7 @@ func TestClientOptionOutQuantity(t *testing.T) {
}
func TestClientOptionInBackups(t *testing.T) {
client, err := NewSAMSSUClientForwarderFromOptions(SetClientInBackups(5))
client, err := NewSAMDGClientForwarderFromOptions(samoptions.SetInBackups(5))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -182,7 +184,7 @@ func TestClientOptionInBackups(t *testing.T) {
}
func TestClientOptionOutBackups(t *testing.T) {
client, err := NewSAMSSUClientForwarderFromOptions(SetClientOutBackups(5))
client, err := NewSAMDGClientForwarderFromOptions(samoptions.SetOutBackups(5))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -190,7 +192,7 @@ func TestClientOptionOutBackups(t *testing.T) {
}
func TestClientOptionReduceIdleQuantity(t *testing.T) {
client, err := NewSAMSSUClientForwarderFromOptions(SetClientReduceIdleQuantity(4))
client, err := NewSAMDGClientForwarderFromOptions(samoptions.SetReduceIdleQuantity(4))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -198,7 +200,7 @@ func TestClientOptionReduceIdleQuantity(t *testing.T) {
}
func TestClientOptionReduceIdleTimeMs(t *testing.T) {
client, err := NewSAMSSUClientForwarderFromOptions(SetClientReduceIdleTimeMs(300000))
client, err := NewSAMDGClientForwarderFromOptions(samoptions.SetReduceIdleTimeMs(300000))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -206,7 +208,7 @@ func TestClientOptionReduceIdleTimeMs(t *testing.T) {
}
func TestClientOptionReduceIdleTime(t *testing.T) {
client, err := NewSAMSSUClientForwarderFromOptions(SetClientReduceIdleTime(6))
client, err := NewSAMDGClientForwarderFromOptions(samoptions.SetReduceIdleTime(6))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -214,7 +216,7 @@ func TestClientOptionReduceIdleTime(t *testing.T) {
}
func TestClientOptionCloseIdleTimeMs(t *testing.T) {
client, err := NewSAMSSUClientForwarderFromOptions(SetClientCloseIdleTimeMs(300000))
client, err := NewSAMDGClientForwarderFromOptions(samoptions.SetCloseIdleTimeMs(300000))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -222,7 +224,7 @@ func TestClientOptionCloseIdleTimeMs(t *testing.T) {
}
func TestClientOptionCloseIdleTime(t *testing.T) {
client, err := NewSAMSSUClientForwarderFromOptions(SetClientCloseIdleTime(6))
client, err := NewSAMDGClientForwarderFromOptions(samoptions.SetCloseIdleTime(6))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -230,7 +232,7 @@ func TestClientOptionCloseIdleTime(t *testing.T) {
}
func TestClientOptionEncryptLease(t *testing.T) {
client, err := NewSAMSSUClientForwarderFromOptions(SetClientEncrypt(true))
client, err := NewSAMDGClientForwarderFromOptions(samoptions.SetEncrypt(true))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
@ -238,7 +240,7 @@ func TestClientOptionEncryptLease(t *testing.T) {
}
func TestClientOptionSaveFile(t *testing.T) {
client, err := NewSAMSSUClientForwarderFromOptions(SetClientSaveFile(true))
client, err := NewSAMDGClientForwarderFromOptions(samoptions.SetSaveFile(true))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}