Set optimized I2P defaults

This commit is contained in:
idk 2020-12-07 01:46:53 -05:00
parent 5d9f633fc9
commit 443875e921
No known key found for this signature in database
GPG key ID: D75C03B39B5E14E1
14 changed files with 229 additions and 137 deletions

View file

@ -32,7 +32,7 @@ func (c *Client) ListenI2P(dest string) (net.Listener, error) {
}
fmt.Println("Listening on destination:", c.Base32()+".b32.i2p")
c, err = c.NewClient()
c, err = c.NewClient(c.id)
if err != nil {
return nil, err
}

View file

@ -11,7 +11,8 @@ import (
"math/rand"
"net"
"strings"
"sync"
// "sync"
"time"
)
// A Client represents a single Connection to the SAM bridge
@ -52,10 +53,9 @@ type Client struct {
debug bool
//NEVER, EVER modify lastaddr or id yourself. They are used internally only.
lastaddr string
id int32
ml sync.Mutex
oml sync.Mutex
id int32
sammin int
sammax int
}
var SAMsigTypes = []string{
@ -66,6 +66,12 @@ var SAMsigTypes = []string{
"SIGNATURE_TYPE=EdDSA_SHA512_Ed25519",
}
var ValidSAMCommands = []string{
"HELLO",
"SESSION",
"STREAM",
}
var (
i2pB64enc *base64.Encoding = base64.NewEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-~")
i2pB32enc *base32.Encoding = base32.NewEncoding("abcdefghijklmnopqrstuvwxyz234567")
@ -83,7 +89,10 @@ func NewClient(addr string) (*Client, error) {
// NewID generates a random number to use as an tunnel name
func (c *Client) NewID() int32 {
return rand.Int31n(math.MaxInt32)
if c.id == 0 {
c.id = rand.Int31n(math.MaxInt32)
}
return c.id
}
// Destination returns the full destination of the local tunnel
@ -127,11 +136,11 @@ func NewClientFromOptions(opts ...func(*Client) error) (*Client, error) {
c.port = "7656"
c.inLength = 3
c.inVariance = 0
c.inQuantity = 1
c.inQuantity = 3
c.inBackups = 1
c.outLength = 3
c.outVariance = 0
c.outQuantity = 1
c.outQuantity = 3
c.outBackups = 1
c.dontPublishLease = true
c.encryptLease = false
@ -140,20 +149,22 @@ func NewClientFromOptions(opts ...func(*Client) error) (*Client, error) {
c.reduceIdleQuantity = 1
c.closeIdle = true
c.closeIdleTime = 600000
c.debug = true
c.debug = false
c.sigType = SAMsigTypes[4]
c.id = 0
c.lastaddr = "invalid"
c.destination = ""
c.leaseSetEncType = "4,0"
c.fromport = ""
c.toport = ""
c.sammin = 0
c.sammax = 1
for _, o := range opts {
if err := o(&c); err != nil {
return nil, err
}
}
conn, err := net.Dial("tcp", c.samaddr())
c.id = c.NewID()
conn, err := net.DialTimeout("tcp", c.samaddr(), 15*time.Minute)
if err != nil {
return nil, err
}
@ -180,7 +191,7 @@ func (c *Client) samaddr() string {
// send the initial handshake command and check that the reply is ok
func (c *Client) hello() error {
r, err := c.sendCmd("HELLO VERSION MIN=3.0 MAX=3.2\n")
r, err := c.sendCmd("HELLO VERSION MIN=3.%d MAX=3.%d\n", c.sammin, c.sammax)
if err != nil {
return err
}
@ -216,8 +227,10 @@ func (c *Client) Close() error {
return c.SamConn.Close()
}
// NewClient generates an exact copy of the client with the same options
func (c *Client) NewClient() (*Client, error) {
// NewClient generates an exact copy of the client with the same options, but
// re-does all the handshaky business so that Dial can pick up right where it
// left off, should the need arise.
func (c *Client) NewClient(id int32) (*Client, error) {
return NewClientFromOptions(
SetHost(c.host),
SetPort(c.port),
@ -238,7 +251,6 @@ func (c *Client) NewClient() (*Client, error) {
SetCloseIdle(c.closeIdle),
SetCloseIdleTime(c.closeIdleTime),
SetCompression(c.compression),
setlastaddr(c.lastaddr),
setid(c.id),
setid(id),
)
}

View file

@ -2,35 +2,28 @@ package goSam
import (
"context"
"fmt"
"log"
"net"
"strings"
)
// DialContext implements the net.DialContext function and can be used for http.Transport
func (c *Client) DialContext(ctx context.Context, network, addr string) (net.Conn, error) {
c.oml.Lock()
defer c.oml.Unlock()
errCh := make(chan error, 1)
connCh := make(chan net.Conn, 1)
go func() {
if conn, err := c.Dial(network, addr); err != nil {
if conn, err := c.DialContextFree(network, addr); err != nil {
errCh <- err
} else if ctx.Err() != nil {
var err error
c, err = c.NewClient()
if err != nil {
conn.Close()
}
log.Println(ctx)
errCh <- ctx.Err()
} else {
connCh <- conn
}
}()
select {
case err := <-errCh:
// var err error
c, err = c.NewClient()
return c.SamConn, err
return nil, err
case conn := <-connCh:
return conn, nil
case <-ctx.Done():
@ -38,42 +31,49 @@ func (c *Client) DialContext(ctx context.Context, network, addr string) (net.Con
}
}
func (c *Client) dialCheck(addr string) (int32, bool) {
if c.lastaddr == "invalid" {
fmt.Println("Preparing to dial new address.")
return c.NewID(), true
} else if c.lastaddr != addr {
fmt.Println("Preparing to dial next new address.")
}
return c.id, false
func (c *Client) Dial(network, addr string) (net.Conn, error) {
return c.DialContext(context.TODO(), network, addr)
}
// Dial implements the net.Dial function and can be used for http.Transport
func (c *Client) Dial(network, addr string) (net.Conn, error) {
c.ml.Lock()
defer c.ml.Unlock()
func (c *Client) DialContextFree(network, addr string) (net.Conn, error) {
portIdx := strings.Index(addr, ":")
if portIdx >= 0 {
addr = addr[:portIdx]
}
addr, err := c.Lookup(addr)
if err != nil {
log.Printf("LOOKUP DIALER ERROR %s %s", addr, err)
return nil, err
}
var test bool
if c.id, test = c.dialCheck(addr); test == true {
c.destination, err = c.CreateStreamSession(c.id, c.destination)
c.destination, err = c.CreateStreamSession(c.id, c.destination)
if err != nil {
c.Close()
d, err := c.NewClient(c.id + 1) /**/
if err != nil {
return nil, err
}
c.lastaddr = addr
d.destination, err = d.CreateStreamSession(d.id, c.destination)
if err != nil {
return nil, err
}
d, err = d.NewClient(d.id)
if err != nil {
return nil, err
}
// d.lastaddr = addr
err = d.StreamConnect(d.id, addr)
if err != nil {
return nil, err
}
c = d
return d.SamConn, nil
}
c, err = c.NewClient()
c, err = c.NewClient(c.id)
if err != nil {
return nil, err
}
err = c.StreamConnect(c.id, addr)
if err != nil {
return nil, err

View file

@ -1,10 +1,11 @@
module github.com/eyedeekay/goSam
require (
github.com/eyedeekay/sam3 v0.32.32-0.20201122050855-f464873c9350
github.com/eyedeekay/sam3 v0.32.32
github.com/getlantern/go-socks5 v0.0.0-20171114193258-79d4dd3e2db5
github.com/getlantern/golog v0.0.0-20201105130739-9586b8bde3a9 // indirect
github.com/getlantern/netx v0.0.0-20190110220209-9912de6f94fd // indirect
github.com/getlantern/ops v0.0.0-20200403153110-8476b16edcd6 // indirect
)
//replace github.com/eyedeekay/gosam v0.1.1-0.20190814195658-27e786578944 => github.com/eyedeekay/goSam ./

View file

@ -6,6 +6,8 @@ github.com/eyedeekay/sam3 v0.32.2/go.mod h1:Y3igFVzN4ybqkkpfUWULGhw7WRp8lieq0ORX
github.com/eyedeekay/sam3 v0.32.31 h1:0fdDAupEQZSETHcyVQAsnFgpYArGJzU+lC2qN6f0GDk=
github.com/eyedeekay/sam3 v0.32.32-0.20201122050855-f464873c9350 h1:8R4zcaWsgANiZ4MKKBPUf9Isct2M1IFVUVZdAMqPCmU=
github.com/eyedeekay/sam3 v0.32.32-0.20201122050855-f464873c9350/go.mod h1:qRA9KIIVxbrHlkj+ZB+OoxFGFgdKeGp1vSgPw26eOVU=
github.com/eyedeekay/sam3 v0.32.32 h1:9Ea1Ere5O8Clx8zYxKnvhrWy7R96Q4FvxlPskYf8VW0=
github.com/eyedeekay/sam3 v0.32.32/go.mod h1:qRA9KIIVxbrHlkj+ZB+OoxFGFgdKeGp1vSgPw26eOVU=
github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 h1:NRUJuo3v3WGC/g5YiyF790gut6oQr5f3FBI88Wv0dx4=
github.com/getlantern/context v0.0.0-20190109183933-c447772a6520/go.mod h1:L+mq6/vvYHKjCX2oez0CgEAJmbq1fbb/oNJIWQkBybY=
github.com/getlantern/errors v1.0.1 h1:XukU2whlh7OdpxnkXhNH9VTLVz0EVPGKDV5K0oWhvzw=
@ -22,6 +24,8 @@ github.com/getlantern/netx v0.0.0-20190110220209-9912de6f94fd h1:mn98vs69Kqw56iK
github.com/getlantern/netx v0.0.0-20190110220209-9912de6f94fd/go.mod h1:wKdY0ikOgzrWSeB9UyBVKPRhjXQ+vTb+BPeJuypUuNE=
github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f h1:wrYrQttPS8FHIRSlsrcuKazukx/xqO/PpLZzZXsF+EA=
github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f/go.mod h1:D5ao98qkA6pxftxoqzibIBBrLSUli+kYnJqrgBf9cIA=
github.com/getlantern/ops v0.0.0-20200403153110-8476b16edcd6 h1:QthAQCekS1YOeYWSvoHI6ZatlG4B+GBDLxV/2ZkBsTA=
github.com/getlantern/ops v0.0.0-20200403153110-8476b16edcd6/go.mod h1:D5ao98qkA6pxftxoqzibIBBrLSUli+kYnJqrgBf9cIA=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw=

View file

@ -37,37 +37,39 @@ func (c *Client) Lookup(name string) (string, error) {
}
func (c *Client) forward(client, conn net.Conn) {
defer client.Close()
defer conn.Close()
go func() {
defer client.Close()
defer conn.Close()
// defer client.Close()
// defer conn.Close()
io.Copy(client, conn)
}()
go func() {
defer client.Close()
defer conn.Close()
// defer client.Close()
// defer conn.Close()
io.Copy(conn, client)
}()
}
func (c *Client) Resolve(ctx context.Context, name string) (context.Context, net.IP, error) {
if c.lastaddr == "invalid" || c.lastaddr != name {
client, err := c.DialContext(ctx, "", name)
if err != nil {
return ctx, nil, err
}
ln, err := net.Listen("tcp", "127.0.0.1:")
if err != nil {
return ctx, nil, err
}
go func() {
for {
conn, err := ln.Accept()
if err != nil {
fmt.Println(err.Error())
}
go c.forward(client, conn)
}
}()
// if c.lastaddr == "invalid" || c.lastaddr != name {
client, err := c.DialContext(ctx, "", name)
if err != nil {
return ctx, nil, err
}
ln, err := net.Listen("tcp", "127.0.0.1:")
if err != nil {
return ctx, nil, err
}
go func() {
for {
conn, err := ln.Accept()
if err != nil {
fmt.Println(err.Error())
}
go c.forward(client, conn)
}
}()
// }
return ctx, nil, nil
}

View file

@ -62,6 +62,32 @@ func SetHost(s string) func(*Client) error {
}
}
func SetSAMMinVersion(i int) func(*Client) error {
return func(c *Client) error {
if i < 0 {
return fmt.Errorf("SAM version must be greater than or equal to 0")
}
if i > 3 {
return fmt.Errorf("SAM version must be less than or equal to 3")
}
c.sammin = i
return nil
}
}
func SetSAMMaxVersion(i int) func(*Client) error {
return func(c *Client) error {
if i < 0 {
return fmt.Errorf("SAM version must be greater than or equal to 0")
}
if i > 3 {
return fmt.Errorf("SAM version must be less than or equal to 3")
}
c.sammin = i
return nil
}
}
//SetLocalDestination sets the local destination of the tunnel from a private
//key
func SetLocalDestination(s string) func(*Client) error {
@ -71,13 +97,6 @@ func SetLocalDestination(s string) func(*Client) error {
}
}
func setlastaddr(s string) func(*Client) error {
return func(c *Client) error {
c.lastaddr = s
return nil
}
}
func setid(s int32) func(*Client) error {
return func(c *Client) error {
c.id = s

View file

@ -44,6 +44,25 @@ func parseReply(line string) (*Reply, error) {
if len(parts) < 3 {
return nil, fmt.Errorf("Malformed Reply.\n%s\n", line)
}
preParseReply := func() []string {
val := ""
quote := false
for _, v := range parts {
if strings.Contains(v, "=\"") {
quote = true
}
if strings.Contains(v, "\"\n") || strings.Contains(v, "\" ") {
quote = false
}
if quote {
val += v + "_"
} else {
val += v + " "
}
}
return strings.Split(strings.TrimSuffix(strings.TrimSpace(val), "_"), " ")
}
parts = preParseReply()
r := &Reply{
Topic: parts[0],
@ -63,9 +82,8 @@ func parseReply(line string) (*Reply, error) {
} else {
kvPair := strings.SplitN(v, "=", 2)
if kvPair != nil {
if len(kvPair) == 1 {
} else if len(kvPair) != 2 {
return nil, fmt.Errorf("Malformed key-value-pair.\n%s\n", kvPair)
if len(kvPair) != 2 {
return nil, fmt.Errorf("Malformed key-value-pair len != 2.\n%s\n", kvPair)
}
}
r.Pairs[kvPair[0]] = kvPair[len(kvPair)-1]

View file

@ -6,6 +6,9 @@ import (
// StreamConnect asks SAM for a TCP-Like connection to dest, has to be called on a new Client
func (c *Client) StreamConnect(id int32, dest string) error {
if dest == "" {
return nil
}
r, err := c.sendCmd("STREAM CONNECT ID=%d DESTINATION=%s %s %s\n", id, dest, c.from(), c.to())
if err != nil {
return err

6
vendor/modules.txt vendored
View file

@ -68,6 +68,8 @@ github.com/couchbase/vellum
github.com/couchbase/vellum/levenshtein
github.com/couchbase/vellum/regexp
github.com/couchbase/vellum/utf8
# github.com/cryptix/goSam v0.1.0
## explicit
# github.com/cznic/b v0.0.0-20181122101859-a26611c4d92d
## explicit
# github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548
@ -81,10 +83,10 @@ github.com/davecgh/go-spew/spew
github.com/dsnet/compress/brotli
github.com/dsnet/compress/internal
github.com/dsnet/compress/internal/errors
# github.com/eyedeekay/goSam v0.32.29
# github.com/eyedeekay/goSam v0.32.29 => ../goSam
## explicit
github.com/eyedeekay/goSam
# github.com/eyedeekay/sam3 v0.32.32-0.20201122050855-f464873c9350
# github.com/eyedeekay/sam3 v0.32.32
github.com/eyedeekay/sam3/i2pkeys
# github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51
## explicit