6 Commits

9 changed files with 66 additions and 16 deletions

View File

@@ -1,6 +1,6 @@
USER_GH=eyedeekay
VERSION=0.32.30
VERSION=0.32.51
packagename=gosam
echo: fmt

View File

@@ -11,8 +11,10 @@ import (
"math/rand"
"net"
"strings"
// "sync"
"sync"
"time"
samkeys "github.com/eyedeekay/goSam/compat"
)
// A Client represents a single Connection to the SAM bridge
@@ -22,9 +24,10 @@ type Client struct {
fromport string
toport string
SamConn net.Conn
SamDGConn DatagramConn
SamConn net.Conn // Control socket
SamDGConn DatagramConn // Datagram socket
rd *bufio.Reader
// d *Client
sigType string
destination string
@@ -53,12 +56,14 @@ type Client struct {
compression bool
debug bool
mutex sync.Mutex
//NEVER, EVER modify lastaddr or id yourself. They are used internally only.
id int32
sammin int
sammax int
}
// SAMsigTypes is a slice of the available signature types
var SAMsigTypes = []string{
"SIGNATURE_TYPE=DSA_SHA1",
"SIGNATURE_TYPE=ECDSA_SHA256_P256",
@@ -88,11 +93,16 @@ func NewClient(addr string) (*Client, error) {
return NewClientFromOptions(SetAddr(addr))
}
func NewID() int32 {
id := rand.Int31n(math.MaxInt32)
fmt.Printf("Initializing new ID: %d\n", id)
return id
}
// NewID generates a random number to use as an tunnel name
func (c *Client) NewID() int32 {
if c.id == 0 {
c.id = rand.Int31n(math.MaxInt32)
fmt.Printf("Initializing new ID: %d\n", c.id)
c.id = NewID()
}
return c.id
}
@@ -178,12 +188,22 @@ func NewClientFromOptions(opts ...func(*Client) error) (*Client, error) {
return &c, c.hello()
}
// ID returns a the current ID of the client as a string
func (p *Client) ID() string {
return fmt.Sprintf("%d", p.NewID())
}
// Addr returns the address of the client as a net.Addr
func (p *Client) Addr() net.Addr {
return nil
keys, err := samkeys.DestToKeys(p.Destination())
if err != nil {
return nil
}
return keys.Addr()
}
func (p *Client) LocalAddr() net.Addr {
return p.Addr()
}
//return the combined host:port of the SAM bridge

View File

@@ -1,3 +1,4 @@
//go:build nettest
// +build nettest
package goSam
@@ -54,27 +55,32 @@ func TestCompositeClient(t *testing.T) {
}
client := &http.Client{Transport: tr}
defer sam.Close()
time.Sleep(time.Second * 30)
x := 0
for x < 15 {
time.Sleep(time.Second * 2)
t.Log("waiting a little while for services to register", (30 - (x * 2)))
x++
}
go func() {
resp, err := client.Get("http://" + listener.Addr().(i2pkeys.I2PAddr).Base32())
if err != nil {
t.Fatalf("Get Error: %q\n", err)
t.Fatalf("Get Error test 1: %q\n", err)
}
defer resp.Body.Close()
}()
time.Sleep(time.Second * 15)
//time.Sleep(time.Second * 15)
go func() {
resp, err := client.Get("http://" + listener2.Addr().(i2pkeys.I2PAddr).Base32())
if err != nil {
t.Fatalf("Get Error: %q\n", err)
t.Fatalf("Get Error test 2: %q\n", err)
}
defer resp.Body.Close()
}()
time.Sleep(time.Second * 15)
//time.Sleep(time.Second * 15)
go func() {
resp, err := client.Get("http://" + listener3.Addr().(i2pkeys.I2PAddr).Base32())
if err != nil {
t.Fatalf("Get Error: %q\n", err)
t.Fatalf("Get Error test 3: %q\n", err)
}
defer resp.Body.Close()
}()

View File

@@ -30,11 +30,14 @@ import (
"time"
)
// Conn Read data from the connection, writes data to te connection
// and logs the data in-between.
type Conn struct {
RWC
conn net.Conn
}
// WrapConn wraps a net.Conn in a Conn.
func WrapConn(c net.Conn) *Conn {
wrap := Conn{
conn: c,
@@ -45,23 +48,29 @@ func WrapConn(c net.Conn) *Conn {
return &wrap
}
// LocalAddr returns the local address of the connection.
func (c *Conn) LocalAddr() net.Addr {
return c.conn.LocalAddr()
}
// RemoteAddr returns the remote address of the connection.
func (c *Conn) RemoteAddr() net.Addr {
return c.conn.RemoteAddr()
}
// SetDeadline sets the read and write deadlines associated with the connection
func (c *Conn) SetDeadline(t time.Time) error {
log.Println("WARNING: SetDeadline() not sure this works")
return c.conn.SetDeadline(t)
}
// SetReadDeadline sets the read deadline associated with the connection
func (c *Conn) SetReadDeadline(t time.Time) error {
log.Println("WARNING: SetReadDeadline() not sure this works")
return c.conn.SetReadDeadline(t)
}
// SetWriteDeadline sets the write deadline associated with the connection
func (c *Conn) SetWriteDeadline(t time.Time) error {
log.Println("WARNING: SetWriteDeadline() not sure this works")
return c.conn.SetWriteDeadline(t)

View File

@@ -5,6 +5,7 @@ import (
"time"
)
// DatagramConn
type DatagramConn interface {
ReadFrom(p []byte) (n int, addr net.Addr, err error)
Read(b []byte) (n int, err error)
@@ -17,3 +18,8 @@ type DatagramConn interface {
SetReadDeadline(t time.Time) error
SetWriteDeadline(t time.Time) error
}
/**
* When datagram support is finished, this will compile.
* var conn DatagramConn = &Client{}
**/

View File

@@ -2,6 +2,7 @@ package goSam
import (
"context"
"fmt"
"log"
"net"
"strings"
@@ -9,6 +10,8 @@ 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.mutex.Lock()
defer c.mutex.Unlock()
errCh := make(chan error, 1)
connCh := make(chan net.Conn, 1)
go func() {
@@ -29,6 +32,7 @@ func (c *Client) DialContext(ctx context.Context, network, addr string) (net.Con
case <-ctx.Done():
return nil, ctx.Err()
}
}
func (c *Client) Dial(network, addr string) (net.Conn, error) {
@@ -49,8 +53,10 @@ func (c *Client) DialContextFree(network, addr string) (net.Conn, error) {
return c.DialStreamingContextFree(addr)
}
// DialDatagramContextFree is a "Dialer" for "Client-Like" Datagram connections.
// It is also not finished. If you need datagram support right now, use sam3.
func (c *Client) DialDatagramContextFree(addr string) (DatagramConn, error) {
return c.SamDGConn, nil
return nil, fmt.Errorf("Datagram support is not finished yet, come back later`")
}
func (c *Client) DialStreamingContextFree(addr string) (net.Conn, error) {

View File

@@ -1,3 +1,4 @@
//go:build nettest
// +build nettest
package goSam

View File

@@ -1,3 +1,4 @@
//go:build nettest
// +build nettest
package goSam

View File

@@ -11,8 +11,9 @@ func init() {
rand.Seed(time.Now().UnixNano())
}
// CreateSession creates a new STREAM Session.
// Returns the Id for the new Client.
// CreateSession creates a new Session of type style, with an optional destination.
// an empty destination is interpreted as "TRANSIENT"
// Returns the destination for the new Client or an error.
func (c *Client) CreateSession(style, dest string) (string, error) {
if dest == "" {
dest = "TRANSIENT"