add the tcp folder and the backward-compatability files

This commit is contained in:
idk
2019-04-20 16:04:16 -04:00
parent 8b4b86b3ee
commit fdf75d99a0
25 changed files with 1863 additions and 398 deletions

View File

@ -1,5 +1,5 @@
GOPATH=$(HOME)/go
#GOPATH=$(HOME)/go
appname = ephsite
packagename = sam-forwarder
@ -27,6 +27,8 @@ echo:
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 "*.go" -exec cat {} \; | nl
find ./tcp/ -name '*.go' -exec cp -rv {} . \;
sed -i '1s|^|//AUTO-GENERATED FOR BACKWARD COMPATIBILITY, USE ./tcp in the future\n|' *.go
## TODO: Remove this, replace with something right
fix-debian:
@ -75,9 +77,9 @@ deps:
go get -u github.com/gtank/cryptopasta
go get -u github.com/zieckey/goini
go get -u github.com/eyedeekay/udptunnel
go get -u github.com/eyedeekay/sam-forwarder
go get -u github.com/eyedeekay/sam-forwarder/i2pkeys
go get -u github.com/eyedeekay/sam-forwarder/i2pkeys/keys
go get -u github.com/eyedeekay/sam-forwarder/tcp
go get -u github.com/eyedeekay/sam-forwarder/udp
go get -u github.com/eyedeekay/sam-forwarder/config
go get -u github.com/eyedeekay/sam-forwarder/manager

View File

@ -1,7 +1,7 @@
package i2ptunconf
import (
"github.com/eyedeekay/sam-forwarder"
"github.com/eyedeekay/sam-forwarder/tcp"
"github.com/eyedeekay/sam-forwarder/udp"
)

View File

@ -1,7 +1,7 @@
package i2ptunconf
import (
"github.com/eyedeekay/sam-forwarder"
"github.com/eyedeekay/sam-forwarder/tcp"
"github.com/eyedeekay/sam-forwarder/udp"
)

View File

@ -1,29 +0,0 @@
package samforwardervpn
import (
"github.com/eyedeekay/sam-forwarder/config"
)
//ClientOption is a SAMClientServerVPN Option
type ClientOption func(*SAMClientVPN) error
func SetClientFilePath(s string) func(*SAMClientVPN) error {
return func(c *SAMClientVPN) error {
c.FilePath = s
return nil
}
}
func SetClientVPNConfig(s *i2ptunconf.Conf) func(*SAMClientVPN) error {
return func(c *SAMClientVPN) error {
c.Config = s
return nil
}
}
func SetClientDest(s string) func(*SAMClientVPN) error {
return func(c *SAMClientVPN) error {
c.ClientDest = s
return nil
}
}

View File

@ -1,120 +0,0 @@
package samforwardervpn
import (
"bytes"
"context"
"fmt"
"io"
"log"
"os"
"os/signal"
"syscall"
"time"
"github.com/eyedeekay/sam-forwarder/config"
"github.com/eyedeekay/sam-forwarder/udp"
"github.com/eyedeekay/udptunnel/tunnel"
)
type SAMClientVPN struct {
// i2p tunnel
I2PTunnel *samforwarderudp.SAMSSUClientForwarder
Config *i2ptunconf.Conf
FilePath string
// VPN tunnel
VPNTunnel udptunnel.Tunnel
ClientDest string
}
func (f *SAMClientVPN) sam() string {
return f.Config.SamHost + ":" + f.Config.SamPort
}
// Target returns the host:port of the local service you want to forward to i2p
func (f *SAMClientVPN) Target() string {
return f.Config.TargetHost + ":" + f.Config.TargetPort
}
func (f *SAMClientVPN) Base32() string {
return f.I2PTunnel.Base32()
}
func NewSAMClientVPN(conf *i2ptunconf.Conf, destination ...string) (*SAMClientVPN, error) {
if len(destination) == 0 {
return NewSAMClientVPNFromOptions(SetClientVPNConfig(conf))
} else if len(destination) == 1 {
return NewSAMClientVPNFromOptions(SetClientVPNConfig(conf), SetClientDest(destination[0]))
} else {
return nil, fmt.Errorf("Error, argument for destination must be len==0 or len==1")
}
}
func NewSAMClientVPNFromOptions(opts ...func(*SAMClientVPN) error) (*SAMClientVPN, error) {
var s SAMClientVPN
s.FilePath = ""
s.ClientDest = ""
for _, o := range opts {
if err := o(&s); err != nil {
return nil, err
}
}
var err error
if s.Config == nil {
if s.FilePath != "" {
s.Config, err = i2ptunconf.NewI2PTunConf(s.FilePath)
if err != nil {
return nil, err
}
} else {
return nil, fmt.Errorf("No VPN configuration provided")
}
}
if s.ClientDest != "" {
s.Config.ClientDest = s.ClientDest
}
if s.Config.ClientDest == "" {
return nil, fmt.Errorf("VPN Client destination cannot be empty")
}
s.I2PTunnel, err = i2ptunconf.NewSAMSSUClientForwarderFromConf(s.Config)
if err != nil {
return nil, err
}
go s.I2PTunnel.Serve()
if !s.Config.Client {
return nil, fmt.Errorf("Error, VPN client marked as server")
} else {
log.Println("VPN client tunnel destination", s.I2PTunnel.Base32())
}
var logBuf bytes.Buffer
Logger := log.New(io.MultiWriter(os.Stderr, &logBuf), "", log.Ldate|log.Ltime|log.Lshortfile)
ctx, cancel := context.WithCancel(context.Background())
go func() {
sigc := make(chan os.Signal, 1)
signal.Notify(sigc, syscall.SIGINT, syscall.SIGTERM)
Logger.Printf("received %v - initiating shutdown", <-sigc)
cancel()
}()
s.VPNTunnel = udptunnel.NewTunnel(!s.Config.Client, s.Config.TunName, "10.76.0.3", s.Target(), "", []uint16{},
"i2pvpn", time.Duration(time.Second*300), Logger)
go s.VPNTunnel.Run(ctx)
return &s, nil
}
// NewSAMVPNForwarderFromConfig generates a new SAMVPNForwarder from a config file
func NewSAMVPNClientForwarderFromConfig(iniFile, SamHost, SamPort string, label ...string) (*SAMClientVPN, 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 NewSAMClientVPN(config)
}
return nil, nil
}

View File

@ -1,22 +0,0 @@
package samforwardervpn
import (
"github.com/eyedeekay/sam-forwarder/config"
)
//Option is a SAMClientServerVPN Option
type Option func(*SAMClientServerVPN) error
func SetFilePath(s string) func(*SAMClientServerVPN) error {
return func(c *SAMClientServerVPN) error {
c.FilePath = s
return nil
}
}
func SetVPNConfig(s *i2ptunconf.Conf) func(*SAMClientServerVPN) error {
return func(c *SAMClientServerVPN) error {
c.Config = s
return nil
}
}

View File

@ -1,105 +0,0 @@
package samforwardervpn
import (
"bytes"
"context"
"fmt"
"io"
"log"
"os"
"os/signal"
"syscall"
"time"
"github.com/eyedeekay/sam-forwarder/config"
"github.com/eyedeekay/sam-forwarder/udp"
"github.com/eyedeekay/udptunnel/tunnel"
)
type SAMClientServerVPN struct {
// i2p tunnel
I2PTunnel *samforwarderudp.SAMSSUForwarder
Config *i2ptunconf.Conf
FilePath string
// VPN tunnel
VPNTunnel udptunnel.Tunnel
}
func (f *SAMClientServerVPN) sam() string {
return f.Config.SamHost + ":" + f.Config.SamPort
}
// Target returns the host:port of the local service you want to forward to i2p
func (f *SAMClientServerVPN) Target() string {
return f.Config.TargetHost + ":" + f.Config.TargetPort
}
func (f *SAMClientServerVPN) Base32() string {
return f.I2PTunnel.Base32()
}
func NewSAMClientServerVPN(conf *i2ptunconf.Conf) (*SAMClientServerVPN, error) {
return NewSAMClientServerVPNFromOptions(SetVPNConfig(conf))
}
func NewSAMClientServerVPNFromOptions(opts ...func(*SAMClientServerVPN) error) (*SAMClientServerVPN, error) {
var s SAMClientServerVPN
s.FilePath = ""
for _, o := range opts {
if err := o(&s); err != nil {
return nil, err
}
}
var err error
if s.Config == nil {
if s.FilePath != "" {
s.Config, err = i2ptunconf.NewI2PTunConf(s.FilePath)
if err != nil {
return nil, err
}
} else {
return nil, fmt.Errorf("No VPN configuration provided")
}
}
s.I2PTunnel, err = i2ptunconf.NewSAMSSUForwarderFromConf(s.Config)
if err != nil {
return nil, err
}
go s.I2PTunnel.Serve()
if !s.Config.Client {
log.Println("VPN server tunnel listening on", s.I2PTunnel.Base32())
} else {
return nil, fmt.Errorf("Error, VPN server marked as client")
}
var logBuf bytes.Buffer
Logger := log.New(io.MultiWriter(os.Stderr, &logBuf), "", log.Ldate|log.Ltime|log.Lshortfile)
ctx, cancel := context.WithCancel(context.Background())
go func() {
sigc := make(chan os.Signal, 1)
signal.Notify(sigc, syscall.SIGINT, syscall.SIGTERM)
Logger.Printf("received %v - initiating shutdown", <-sigc)
cancel()
}()
s.VPNTunnel = udptunnel.NewTunnel(!s.Config.Client, s.Config.TunName, "10.76.0.2", s.Target(), "", []uint16{},
"i2pvpn", time.Duration(time.Second*300), Logger)
go s.VPNTunnel.Run(ctx)
return &s, nil
}
// NewSAMVPNClientForwarderFromConfig generates a new SAMVPNForwarder from a config file
func NewSAMVPNForwarderFromConfig(iniFile, SamHost, SamPort string, label ...string) (*SAMClientServerVPN, 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 NewSAMClientServerVPN(config)
}
return nil, nil
}

View File

@ -1,54 +0,0 @@
package samforwardervpn
import (
"github.com/eyedeekay/sam-forwarder/config"
"io/ioutil"
"log"
"net/http"
"testing"
"time"
)
func echo() {
http.Handle("/", http.FileServer(http.Dir("../server_test/www")))
log.Fatal(http.ListenAndServe("0.0.0.0:8022", nil))
}
func TestVPN(t *testing.T) {
log.Println("Setting up VPN")
go echo()
if sconfig, err := i2ptunconf.NewI2PTunConf("../etc/i2pvpn/i2pvpn.ini"); err == nil {
if vpn, err := NewSAMClientServerVPN(sconfig); err != nil {
t.Fatal(err)
} else {
time.Sleep(time.Duration(30 * time.Second))
log.Println(&vpn)
if config, err := i2ptunconf.NewI2PTunConf("../etc/i2pvpn/i2pvpnclient.ini"); err == nil {
if vpnc, err := NewSAMClientVPN(config, vpn.Base32()); err != nil {
t.Fatal(err)
} else {
log.Println(&vpnc)
time.Sleep(time.Duration(30 * time.Second))
resp, err := http.Get("http://10.76.0.2:8022/test.html")
if err != nil {
t.Fatal(err)
}
defer resp.Body.Close()
if resp.StatusCode == http.StatusOK {
bodyBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
t.Fatal(err)
}
log.Println(string(bodyBytes))
}
}
} else {
t.Fatal(err)
}
}
} else {
t.Fatal(err)
}
}

View File

@ -10,7 +10,7 @@ import (
)
import (
"github.com/eyedeekay/littleboss"
"crawshaw.io/littleboss"
"github.com/eyedeekay/sam-forwarder/config"
"github.com/eyedeekay/sam-forwarder/manager"
"github.com/eyedeekay/samcatd-web"

View File

@ -15,8 +15,8 @@ import (
)
import (
"github.com/eyedeekay/sam-forwarder"
"github.com/eyedeekay/sam-forwarder/config"
"github.com/eyedeekay/sam-forwarder/tcp"
)
var cfg = &tls.Config{

View File

@ -1,3 +1,4 @@
//AUTO-GENERATED FOR BACKWARD COMPATIBILITY, USE ./tcp in the future
package samforwarder
import (

View File

@ -1,3 +1,4 @@
//AUTO-GENERATED FOR BACKWARD COMPATIBILITY, USE ./tcp in the future
package samforwarder
import (
@ -12,6 +13,7 @@ import (
import (
"github.com/eyedeekay/sam-forwarder/i2pkeys"
"github.com/eyedeekay/sam3"
"github.com/eyedeekay/sam3/i2pkeys"
)
// SAMClientForwarder is a tcp proxy that automatically forwards ports to i2p
@ -25,10 +27,10 @@ type SAMClientForwarder struct {
TargetPort string
samConn *sam3.SAM
SamKeys sam3.I2PKeys
SamKeys i2pkeys.I2PKeys
connectStream *sam3.StreamSession
dest string
addr sam3.I2PAddr
addr i2pkeys.I2PAddr
publishConnection net.Listener
FilePath string
@ -43,7 +45,7 @@ type SAMClientForwarder struct {
leaseSetKey string
leaseSetPrivateKey string
leaseSetPrivateSigningKey string
LeaseSetKeys *sam3.I2PKeys
LeaseSetKeys *i2pkeys.I2PKeys
inAllowZeroHop string
outAllowZeroHop string
inLength string
@ -295,12 +297,12 @@ func NewSAMClientForwarderFromOptions(opts ...func(*SAMClientForwarder) error) (
if s.save {
log.Println("Saving i2p keys")
}
if s.SamKeys, err = i2pkeys.Load(s.FilePath, s.TunName, s.passfile, s.samConn, s.save); err != nil {
if s.SamKeys, err = sfi2pkeys.Load(s.FilePath, s.TunName, s.passfile, s.samConn, s.save); err != nil {
return nil, err
}
log.Println("Destination keys generated, tunnel name:", s.TunName)
if s.save {
if err := i2pkeys.Save(s.FilePath, s.TunName, s.passfile, s.SamKeys); err != nil {
if err := sfi2pkeys.Save(s.FilePath, s.TunName, s.passfile, s.SamKeys); err != nil {
return nil, err
}
log.Println("Saved tunnel keys for", s.TunName)

View File

@ -1,3 +1,4 @@
//AUTO-GENERATED FOR BACKWARD COMPATIBILITY, USE ./tcp in the future
package samforwarder
import (

View File

@ -1,3 +1,4 @@
//AUTO-GENERATED FOR BACKWARD COMPATIBILITY, USE ./tcp in the future
package samforwarder
import (
@ -15,6 +16,7 @@ import (
import (
"github.com/eyedeekay/sam-forwarder/i2pkeys"
"github.com/eyedeekay/sam3"
"github.com/eyedeekay/sam3/i2pkeys"
)
//SAMForwarder is a structure which automatically configured the forwarding of
@ -28,7 +30,7 @@ type SAMForwarder struct {
TargetPort string
samConn *sam3.SAM
SamKeys sam3.I2PKeys
SamKeys i2pkeys.I2PKeys
publishStream *sam3.StreamSession
publishListen *sam3.StreamListener
publishConnection net.Conn
@ -47,7 +49,7 @@ type SAMForwarder struct {
leaseSetKey string
leaseSetPrivateKey string
leaseSetPrivateSigningKey string
LeaseSetKeys *sam3.I2PKeys
LeaseSetKeys *i2pkeys.I2PKeys
inAllowZeroHop string
outAllowZeroHop string
inLength string
@ -205,7 +207,7 @@ func (f SAMForwarder) HTTPRequestBytes(conn *sam3.SAMConn) ([]byte, *http.Reques
if err != nil {
return nil, nil, err
}
dest := conn.RemoteAddr().(sam3.I2PAddr)
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())
@ -400,12 +402,12 @@ func NewSAMForwarderFromOptions(opts ...func(*SAMForwarder) error) (*SAMForwarde
if s.save {
log.Println("Saving i2p keys")
}
if s.SamKeys, err = i2pkeys.Load(s.FilePath, s.TunName, s.passfile, s.samConn, s.save); err != nil {
if s.SamKeys, err = sfi2pkeys.Load(s.FilePath, s.TunName, s.passfile, s.samConn, s.save); err != nil {
return nil, err
}
log.Println("Destination keys generated, tunnel name:", s.TunName)
if s.save {
if err := i2pkeys.Save(s.FilePath, s.TunName, s.passfile, s.SamKeys); err != nil {
if err := sfi2pkeys.Save(s.FilePath, s.TunName, s.passfile, s.SamKeys); err != nil {
return nil, err
}
log.Println("Saved tunnel keys for", s.TunName)

View File

@ -1,3 +1,4 @@
//AUTO-GENERATED FOR BACKWARD COMPATIBILITY, USE ./tcp in the future
package samforwarder
import (

View File

@ -1,4 +1,4 @@
package i2pkeys
package sfi2pkeys
import (
"log"
@ -8,6 +8,7 @@ import (
"github.com/eyedeekay/sam-forwarder/i2pkeys/keys"
//"github.com/eyedeekay/sam-forwarder/i2pkeys/password"
"github.com/eyedeekay/sam3"
"github.com/eyedeekay/sam3/i2pkeys"
)
func Encrypt(i2pkeypath, aeskeypath string) error {
@ -18,13 +19,13 @@ func Decrypt(i2pkeypath, aeskeypath string) error {
return i2pkeyscrypt.DecryptKey(i2pkeypath, aeskeypath)
}
func Save(FilePath, TunName, passfile string, SamKeys sam3.I2PKeys) error {
func Save(FilePath, TunName, passfile string, SamKeys i2pkeys.I2PKeys) error {
if _, err := os.Stat(filepath.Join(FilePath, TunName+".i2pkeys")); os.IsNotExist(err) {
file, err := os.Create(filepath.Join(FilePath, TunName+".i2pkeys"))
if err != nil {
return err
}
err = sam3.StoreKeysIncompat(SamKeys, file)
err = i2pkeys.StoreKeysIncompat(SamKeys, file)
if err != nil {
return err
}
@ -42,7 +43,7 @@ func Save(FilePath, TunName, passfile string, SamKeys sam3.I2PKeys) error {
//if err != nil {
//return err
//}
SamKeys, err = sam3.LoadKeysIncompat(file)
SamKeys, err = i2pkeys.LoadKeysIncompat(file)
if err != nil {
return err
}
@ -54,26 +55,26 @@ func Save(FilePath, TunName, passfile string, SamKeys sam3.I2PKeys) error {
return nil
}
func Load(FilePath, TunName, passfile string, samConn *sam3.SAM, save bool) (sam3.I2PKeys, error) {
if ! save {
return samConn.NewKeys()
}
func Load(FilePath, TunName, passfile string, samConn *sam3.SAM, save bool) (i2pkeys.I2PKeys, error) {
if !save {
return samConn.NewKeys()
}
if _, err := os.Stat(filepath.Join(FilePath, TunName+".i2pkeys")); os.IsNotExist(err) {
log.Println("Generating keys from SAM bridge")
SamKeys, err := samConn.NewKeys()
if err != nil {
return sam3.I2PKeys{}, err
return i2pkeys.I2PKeys{}, err
}
return SamKeys, nil
}
log.Println("Generating keys from disk")
file, err := os.Open(filepath.Join(FilePath, TunName+".i2pkeys"))
if err != nil {
return sam3.I2PKeys{}, err
return i2pkeys.I2PKeys{}, err
}
//err = Decrypt(filepath.Join(FilePath, TunName+".i2pkeys"), passfile)
//if err != nil {
//return sam3.I2PKeys{}, err
//return i2pkeys.I2PKeys{}, err
//}
return sam3.LoadKeysIncompat(file)
return i2pkeys.LoadKeysIncompat(file)
}

View File

@ -1,4 +1,4 @@
package i2pkeys
package sfi2pkeys
import (
//"os"

View File

@ -7,9 +7,8 @@ import (
)
import (
"github.com/eyedeekay/sam-forwarder"
"github.com/eyedeekay/sam-forwarder/config"
"github.com/eyedeekay/sam-forwarder/csvpn"
"github.com/eyedeekay/sam-forwarder/tcp"
"github.com/eyedeekay/sam-forwarder/udp"
)
@ -32,8 +31,6 @@ type SAMManager struct {
clientforwarders []*samforwarder.SAMClientForwarder
udpforwarders []*samforwarderudp.SAMSSUForwarder
udpclientforwarders []*samforwarderudp.SAMSSUClientForwarder
vpnforwarders []*samforwardervpn.SAMClientServerVPN
vpnclientforwarders []*samforwardervpn.SAMClientVPN
}
func stringify(s []string) string {
@ -242,20 +239,6 @@ func NewSAMManagerFromOptions(opts ...func(*SAMManager) error) (*SAMManager, err
} else {
return nil, fmt.Errorf(e.Error())
}
case "vpnserver":
if f, e := samforwardervpn.NewSAMVPNForwarderFromConfig(s.FilePath, s.SamHost, s.SamPort, label); e == nil {
log.Println("found vpnclient under", label)
s.vpnforwarders = append(s.vpnforwarders, f)
} else {
return nil, fmt.Errorf(e.Error())
}
case "vpnclient":
if f, e := samforwardervpn.NewSAMVPNClientForwarderFromConfig(s.FilePath, s.SamHost, s.SamPort, label); e == nil {
log.Println("found vpnclient under", label)
s.vpnclientforwarders = append(s.vpnclientforwarders, f)
} else {
return nil, fmt.Errorf(e.Error())
}
default:
if f, e := i2ptunconf.NewSAMForwarderFromConfig(s.FilePath, s.SamHost, s.SamPort, label); e == nil {
log.Println("found server under", label)
@ -308,20 +291,6 @@ func NewSAMManagerFromOptions(opts ...func(*SAMManager) error) (*SAMManager, err
} else {
return nil, fmt.Errorf(e.Error())
}
case "vpnserver":
if f, e := samforwardervpn.NewSAMVPNForwarderFromConfig(s.FilePath, s.SamHost, s.SamPort); e == nil {
log.Println("found default vpnserver")
s.vpnforwarders = append(s.vpnforwarders, f)
} else {
return nil, fmt.Errorf(e.Error())
}
case "vpnclient":
if f, e := samforwardervpn.NewSAMVPNClientForwarderFromConfig(s.FilePath, s.SamHost, s.SamPort); e == nil {
log.Println("found default vpnclient")
s.vpnclientforwarders = append(s.vpnclientforwarders, f)
} else {
return nil, fmt.Errorf(e.Error())
}
default:
if f, e := i2ptunconf.NewSAMClientForwarderFromConfig(s.FilePath, s.SamHost, s.SamPort); e == nil {
log.Println("found default client")

View File

@ -0,0 +1,391 @@
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
}
}
//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
}
}

310
tcp/forwarder-client.go Normal file
View File

@ -0,0 +1,310 @@
package samforwarder
import (
"io"
"log"
"net"
//"os"
//"path/filepath"
"strings"
)
import (
"github.com/eyedeekay/sam-forwarder/i2pkeys"
"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
connectStream *sam3.StreamSession
dest string
addr i2pkeys.I2PAddr
publishConnection net.Listener
FilePath string
file io.ReadWriter
save bool
// samcatd options
passfile 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
}
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(),
}
}
func (f SAMClientForwarder) Cleanup() {
f.connectStream.Close()
f.publishConnection.Close()
f.samConn.Close()
}
func (f SAMClientForwarder) Print() string {
var r string
r += "name=" + f.TunName + "\n"
r += "type=" + f.Type + "\n"
r += "base32=" + f.Base32() + "\n"
r += "base64=" + f.Base64() + "\n"
r += "dest=" + f.dest + "\n"
r += "ntcpclient\n"
for _, s := range f.print() {
r += s + "\n"
}
return strings.Replace(r, "\n\n", "\n", -1)
return r
}
func (f SAMClientForwarder) 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 SAMClientForwarder) accesslisttype() string {
if f.accessListType == "whitelist" {
return "i2cp.enableAccessList=true"
} else if f.accessListType == "blacklist" {
return "i2cp.enableBlackList=true"
} else if f.accessListType == "none" {
return ""
}
return ""
}
func (f SAMClientForwarder) 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 SAMClientForwarder) 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 SAMClientForwarder) Target() string {
return f.TargetHost + ":" + f.TargetPort
}
// Destination returns the destination of the i2p service you want to forward locally
func (f SAMClientForwarder) Destination() string {
return f.addr.Base32()
}
func (f SAMClientForwarder) sam() string {
return f.SamHost + ":" + f.SamPort
}
//Base32 returns the base32 address of the local destination
func (f SAMClientForwarder) Base32() string {
return f.SamKeys.Addr().Base32()
}
//Base64 returns the base64 address of the local destiantion
func (f SAMClientForwarder) Base64() string {
return f.SamKeys.Addr().Base64()
}
func (f SAMClientForwarder) forward(conn net.Conn) {
client, err := f.connectStream.DialI2P(f.addr)
if err != nil {
log.Fatalf("Dial failed: %v", err)
}
log.Printf("Connected to localhost %v\n", conn)
go func() {
defer client.Close()
defer conn.Close()
io.Copy(client, conn)
}()
go func() {
defer client.Close()
defer conn.Close()
io.Copy(conn, client)
}()
}
//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 {
return err
}
if f.connectStream, err = f.samConn.NewStreamSession(f.TunName, f.SamKeys, f.print()); err != nil {
log.Println("Stream Creation error:", err.Error())
return err
}
log.Println("SAM stream session established.")
for {
conn, err := f.publishConnection.Accept()
if err != nil {
return err
}
log.Println("Forwarding client to i2p address:", f.addr.Base32())
go f.forward(conn)
}
}
//Close shuts the whole thing down.
func (f SAMClientForwarder) Close() error {
var err error
err = f.samConn.Close()
err = f.connectStream.Close()
err = f.publishConnection.Close()
return err
}
//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))
}
//NewSAMClientForwarderFromOptions makes a new SAM forwarder with default options, accepts host:port arguments
func NewSAMClientForwarderFromOptions(opts ...func(*SAMClientForwarder) 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"
for _, o := range opts {
if err := o(&s); err != nil {
return nil, err
}
}
if s.publishConnection, err = net.Listen("tcp", s.TargetHost+":"+s.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 {
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
}
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("Saved tunnel keys for", s.TunName)
}
return &s, nil
}

412
tcp/forwarder-options.go Normal file
View File

@ -0,0 +1,412 @@
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 {
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
}
}
}
//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
return nil
}
}

415
tcp/forwarder.go Normal file
View File

@ -0,0 +1,415 @@
package samforwarder
import (
"bufio"
"io"
"log"
"net"
"net/http"
"net/http/httputil"
//"os"
//"path/filepath"
"strings"
)
import (
"github.com/eyedeekay/sam-forwarder/i2pkeys"
"github.com/eyedeekay/sam3"
"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
publishStream *sam3.StreamSession
publishListen *sam3.StreamListener
publishConnection net.Conn
FilePath string
file io.ReadWriter
save bool
Type string
// samcatd options
passfile 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
clientLock bool
connLock bool
connClientLock bool
connConnLock bool
}
var err error
func (f SAMForwarder) Cleanup() {
f.publishStream.Close()
f.publishListen.Close()
f.publishConnection.Close()
f.samConn.Close()
}
/*func (f SAMForwarder) targetForPort443() string {
if f.TargetForPort443 != "" {
return "targetForPort.4443=" + f.TargetHost + ":" + f.TargetForPort443
}
return ""
}*/
func (f SAMForwarder) 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 SAMForwarder) Print() string {
var r string
r += "name=" + f.TunName + "\n"
r += "type=" + f.Type + "\n"
r += "base32=" + f.Base32() + "\n"
r += "base64=" + f.Base64() + "\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 SAMForwarder) 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 SAMForwarder) accesslisttype() string {
if f.accessListType == "whitelist" {
return "i2cp.enableAccessList=true"
} else if f.accessListType == "blacklist" {
return "i2cp.enableBlackList=true"
} else if f.accessListType == "none" {
return ""
}
return ""
}
func (f SAMForwarder) 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 SAMForwarder) 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 SAMForwarder) Target() string {
return f.TargetHost + ":" + f.TargetPort
}
func (f SAMForwarder) sam() string {
return f.SamHost + ":" + f.SamPort
}
func (f SAMForwarder) HTTPRequestBytes(conn *sam3.SAMConn) ([]byte, *http.Request, error) {
var request *http.Request
var retrequest []byte
var err error
request, err = http.ReadRequest(bufio.NewReader(conn))
if err != nil {
return nil, nil, err
}
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())
if retrequest, err = httputil.DumpRequest(request, true); err != nil {
return nil, nil, err
}
return retrequest, request, nil
}
func (f SAMForwarder) HTTPResponseBytes(conn net.Conn, req *http.Request) ([]byte, error) {
var response *http.Response
var retresponse []byte
var err error
response, err = http.ReadResponse(bufio.NewReader(conn), req)
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
}
return retresponse, nil
}
func (f SAMForwarder) clientUnlockAndClose(cli, conn bool, client net.Conn) {
if cli {
f.clientLock = cli
}
if conn {
f.connLock = conn
}
if f.clientLock && f.connLock {
client.Close()
f.clientLock = false
f.connLock = false
}
}
func (f SAMForwarder) connUnlockAndClose(cli, conn bool, connection *sam3.SAMConn) {
if cli {
f.connClientLock = cli
}
if conn {
f.connConnLock = conn
}
if f.connClientLock && f.connConnLock {
connection.Close()
f.connClientLock = false
f.connConnLock = false
}
}
func (f SAMForwarder) forward(conn *sam3.SAMConn) { //(conn net.Conn) {
var request *http.Request
var requestbytes []byte
var responsebytes []byte
var err error
var client net.Conn
if client, err = net.Dial("tcp", f.Target()); err != nil {
log.Fatalf("Dial failed: %v", err)
}
go func() {
if f.Type == "http" {
defer f.clientUnlockAndClose(true, false, client)
defer f.connUnlockAndClose(false, true, conn)
if requestbytes, request, err = f.HTTPRequestBytes(conn); err == nil {
log.Printf("Forwarding modified request: \n\t %s", string(requestbytes))
client.Write(requestbytes)
} else {
log.Println("Error: ", requestbytes, err)
}
} else {
defer client.Close()
defer conn.Close()
io.Copy(client, conn)
}
}()
go func() {
if f.Type == "http" {
defer f.clientUnlockAndClose(false, true, client)
defer f.connUnlockAndClose(true, false, conn)
if responsebytes, err = f.HTTPResponseBytes(client, request); err == nil {
log.Printf("Forwarding modified response: \n\t%s", string(responsebytes))
conn.Write(responsebytes)
} else {
log.Println("Response Error: ", responsebytes, err)
}
} else {
defer client.Close()
defer conn.Close()
io.Copy(conn, client)
}
}()
}
//Base32 returns the base32 address where the local service is being forwarded
func (f SAMForwarder) Base32() string {
return f.SamKeys.Addr().Base32()
}
//Base64 returns the base64 address where the local service is being forwarded
func (f SAMForwarder) Base64() string {
return f.SamKeys.Addr().Base64()
}
//Serve starts the SAM connection and and forwards the local host:port to i2p
func (f SAMForwarder) Serve() error {
//lsk, lspk, lspsk := f.leasesetsettings()
if f.publishStream, err = f.samConn.NewStreamSession(f.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 {
return err
}
log.Println("Starting Listener.")
b := string(f.SamKeys.Addr().Base32())
log.Println("SAM Listener created,", b)
for {
conn, err := f.publishListen.AcceptI2P()
if err != nil {
log.Fatalf("ERROR: failed to accept listener: %v", err)
}
log.Printf("Accepted connection %v\n", conn)
go f.forward(conn)
}
}
//Close shuts the whole thing down.
func (f SAMForwarder) Close() error {
var err error
err = f.samConn.Close()
err = f.publishStream.Close()
err = f.publishListen.Close()
err = f.publishConnection.Close()
return err
}
//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))
}
//NewSAMForwarderFromOptions makes a new SAM forwarder with default options, accepts host:port arguments
func NewSAMForwarderFromOptions(opts ...func(*SAMForwarder) 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.clientLock = false
s.connLock = false
s.messageReliability = "none"
s.passfile = ""
for _, o := range opts {
if err := o(&s); 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 {
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
}
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("Saved tunnel keys for", s.TunName)
}
return &s, nil
}

286
tcp/forwarder_test.go Normal file
View File

@ -0,0 +1,286 @@
package samforwarder
import (
"log"
"testing"
)
func TestOptionHost(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetHost("127.0.0.1"))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionPort(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetPort("8080"))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionInLength(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetInLength(3))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionOutLength(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetInLength(3))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionInVariance(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetInVariance(1))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionOutVariance(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetOutVariance(1))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionInQuantity(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetInQuantity(6))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionOutQuantity(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetOutQuantity(6))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionInBackups(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetInBackups(5))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionOutBackups(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetOutBackups(5))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionReduceIdleQuantity(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetReduceIdleQuantity(4))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionReduceIdleTimeMs(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetReduceIdleTimeMs(300000))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionReduceIdleTime(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetReduceIdleTime(6))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionCloseIdleTimeMs(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetCloseIdleTimeMs(300000))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionCloseIdleTime(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetCloseIdleTime(6))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionEncryptLease(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetEncrypt(true))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestOptionSaveFile(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetSaveFile(true))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestClientOptionHost(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientHost("127.0.0.1"))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestClientOptionPort(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientSAMPort("7656"))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestClientOptionInLength(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientInLength(3))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestClientOptionOutLength(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientInLength(3))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestClientOptionInVariance(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientInVariance(1))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestClientOptionOutVariance(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientOutVariance(1))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestClientOptionInQuantity(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientInQuantity(6))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestClientOptionOutQuantity(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientOutQuantity(6))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestClientOptionInBackups(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientInBackups(5))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestClientOptionOutBackups(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientOutBackups(5))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestClientOptionReduceIdleQuantity(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientReduceIdleQuantity(4))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestClientOptionReduceIdleTimeMs(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientReduceIdleTimeMs(300000))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestClientOptionReduceIdleTime(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientReduceIdleTime(6))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestClientOptionCloseIdleTimeMs(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientCloseIdleTimeMs(300000))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestClientOptionCloseIdleTime(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientCloseIdleTime(6))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestClientOptionEncryptLease(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientEncrypt(true))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
func TestClientOptionSaveFile(t *testing.T) {
client, err := NewSAMClientForwarderFromOptions(SetClientSaveFile(true))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}
/*func TestOptionTargetForPort443(t *testing.T) {
client, err := NewSAMForwarderFromOptions(SetTargetForPort443("443"))
if err != nil {
t.Fatalf("NewSAMForwarder() Error: %q\n", err)
}
log.Println(client.Base32())
}*/

View File

@ -13,6 +13,7 @@ import (
import (
"github.com/eyedeekay/sam-forwarder/i2pkeys"
"github.com/eyedeekay/sam3"
"github.com/eyedeekay/sam3/i2pkeys"
)
//SAMSSUClientForwarder is a structure which automatically configured the forwarding of
@ -27,10 +28,10 @@ type SAMSSUClientForwarder struct {
TargetPort string
samConn *sam3.SAM
SamKeys sam3.I2PKeys
SamKeys i2pkeys.I2PKeys
connectStream *sam3.DatagramSession
dest string
addr sam3.I2PAddr
addr i2pkeys.I2PAddr
publishConnection net.PacketConn
FilePath string
@ -296,12 +297,12 @@ func NewSAMSSUClientForwarderFromOptions(opts ...func(*SAMSSUClientForwarder) er
if s.save {
log.Println("Saving i2p keys")
}
if s.SamKeys, err = i2pkeys.Load(s.FilePath, s.TunName, s.passfile, s.samConn, s.save); err != nil {
if s.SamKeys, err = sfi2pkeys.Load(s.FilePath, s.TunName, s.passfile, s.samConn, s.save); err != nil {
return nil, err
}
log.Println("Destination keys generated, tunnel name:", s.TunName)
if s.save {
if err := i2pkeys.Save(s.FilePath, s.TunName, s.passfile, s.SamKeys); err != nil {
if err := sfi2pkeys.Save(s.FilePath, s.TunName, s.passfile, s.SamKeys); err != nil {
return nil, err
}
log.Println("Saved tunnel keys for", s.TunName)

View File

@ -13,6 +13,7 @@ import (
import (
"github.com/eyedeekay/sam-forwarder/i2pkeys"
"github.com/eyedeekay/sam3"
"github.com/eyedeekay/sam3/i2pkeys"
)
//SAMSSUForwarder is a structure which automatically configured the forwarding of
@ -27,7 +28,7 @@ type SAMSSUForwarder struct {
TargetPort string
samConn *sam3.SAM
SamKeys sam3.I2PKeys
SamKeys i2pkeys.I2PKeys
publishConnection *sam3.DatagramSession
clientConnection net.PacketConn
@ -292,12 +293,12 @@ func NewSAMSSUForwarderFromOptions(opts ...func(*SAMSSUForwarder) error) (*SAMSS
if s.save {
log.Println("Saving i2p keys")
}
if s.SamKeys, err = i2pkeys.Load(s.FilePath, s.TunName, s.passfile, s.samConn, s.save); err != nil {
if s.SamKeys, err = sfi2pkeys.Load(s.FilePath, s.TunName, s.passfile, s.samConn, s.save); err != nil {
return nil, err
}
log.Println("Destination keys generated, tunnel name:", s.TunName)
if s.save {
if err := i2pkeys.Save(s.FilePath, s.TunName, s.passfile, s.SamKeys); err != nil {
if err := sfi2pkeys.Save(s.FilePath, s.TunName, s.passfile, s.SamKeys); err != nil {
return nil, err
}
log.Println("Saved tunnel keys for", s.TunName)