Allow clients to force a handshake at a specific SAM version or between SAM versions
This commit is contained in:
16
client.go
16
client.go
@ -11,7 +11,7 @@ import (
|
||||
"math/rand"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
// "sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -53,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{
|
||||
@ -153,18 +152,19 @@ func NewClientFromOptions(opts ...func(*Client) error) (*Client, error) {
|
||||
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
|
||||
}
|
||||
}
|
||||
c.id = c.NewID()
|
||||
conn, err := net.DialTimeout("tcp", c.samaddr(), 3*time.Minute)
|
||||
conn, err := net.DialTimeout("tcp", c.samaddr(), 15*time.Minute)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -191,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
|
||||
}
|
||||
|
40
dial.go
40
dial.go
@ -9,8 +9,6 @@ import (
|
||||
|
||||
// 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() {
|
||||
@ -33,25 +31,12 @@ func (c *Client) DialContext(ctx context.Context, network, addr string) (net.Con
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) dialCheck(addr string) (int32, bool) {
|
||||
if c.lastaddr == "invalid" {
|
||||
return c.NewID(), true
|
||||
// } else if addr == "" {
|
||||
// return c.id, false
|
||||
} else if c.lastaddr != addr {
|
||||
return c.NewID(), true
|
||||
}
|
||||
return c.NewID(), false
|
||||
}
|
||||
|
||||
func (c *Client) Dial(network, addr string) (net.Conn, error) {
|
||||
return c.DialContextFree(network, addr)
|
||||
return c.DialContext(context.TODO(), network, addr)
|
||||
}
|
||||
|
||||
// Dial implements the net.Dial function and can be used for http.Transport
|
||||
func (c *Client) DialContextFree(network, addr string) (net.Conn, error) {
|
||||
c.ml.Lock()
|
||||
defer c.ml.Unlock()
|
||||
portIdx := strings.Index(addr, ":")
|
||||
if portIdx >= 0 {
|
||||
addr = addr[:portIdx]
|
||||
@ -62,31 +47,36 @@ func (c *Client) DialContextFree(network, addr string) (net.Conn, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// var test bool
|
||||
//c.id, _ = c.dialCheck(addr)
|
||||
// log.Println("Address indicates we need to dial a new session.")
|
||||
// if test {
|
||||
c.destination, err = c.CreateStreamSession(c.id, c.destination)
|
||||
if err != nil {
|
||||
c, err = c.NewClient(c.id + 1)
|
||||
c.Close()
|
||||
d, err := c.NewClient(c.id + 1) /**/
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.destination, err = c.CreateStreamSession(c.id, c.destination)
|
||||
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.id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.lastaddr = addr
|
||||
err = c.StreamConnect(c.id, addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//}
|
||||
return c.SamConn, nil
|
||||
}
|
||||
|
3
go.mod
3
go.mod
@ -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 ./
|
||||
|
4
go.sum
4
go.sum
@ -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=
|
||||
|
46
naming.go
46
naming.go
@ -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
|
||||
}
|
||||
|
33
options.go
33
options.go
@ -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
|
||||
|
Reference in New Issue
Block a user