Dial/Hangup Hack. If the connection is closed because of an error, re-dial it from within the dial function itself by incrementing the ID and creating a new session on top of the old one.
This commit is contained in:
@ -32,7 +32,7 @@ func (c *Client) ListenI2P(dest string) (net.Listener, error) {
|
|||||||
}
|
}
|
||||||
fmt.Println("Listening on destination:", c.Base32()+".b32.i2p")
|
fmt.Println("Listening on destination:", c.Base32()+".b32.i2p")
|
||||||
|
|
||||||
c, err = c.NewClient()
|
c, err = c.NewClient(c.id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
18
client.go
18
client.go
@ -67,6 +67,12 @@ var SAMsigTypes = []string{
|
|||||||
"SIGNATURE_TYPE=EdDSA_SHA512_Ed25519",
|
"SIGNATURE_TYPE=EdDSA_SHA512_Ed25519",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ValidSAMCommands = []string{
|
||||||
|
"HELLO",
|
||||||
|
"SESSION",
|
||||||
|
"STREAM",
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
i2pB64enc *base64.Encoding = base64.NewEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-~")
|
i2pB64enc *base64.Encoding = base64.NewEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-~")
|
||||||
i2pB32enc *base32.Encoding = base32.NewEncoding("abcdefghijklmnopqrstuvwxyz234567")
|
i2pB32enc *base32.Encoding = base32.NewEncoding("abcdefghijklmnopqrstuvwxyz234567")
|
||||||
@ -143,7 +149,7 @@ func NewClientFromOptions(opts ...func(*Client) error) (*Client, error) {
|
|||||||
c.reduceIdleTime = 300000
|
c.reduceIdleTime = 300000
|
||||||
c.reduceIdleQuantity = 1
|
c.reduceIdleQuantity = 1
|
||||||
c.closeIdle = true
|
c.closeIdle = true
|
||||||
c.closeIdleTime = 60000000
|
c.closeIdleTime = 600000
|
||||||
c.debug = false
|
c.debug = false
|
||||||
c.sigType = SAMsigTypes[4]
|
c.sigType = SAMsigTypes[4]
|
||||||
c.id = 0
|
c.id = 0
|
||||||
@ -157,6 +163,7 @@ func NewClientFromOptions(opts ...func(*Client) error) (*Client, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
c.id = c.NewID()
|
||||||
conn, err := net.DialTimeout("tcp", c.samaddr(), 3*time.Minute)
|
conn, err := net.DialTimeout("tcp", c.samaddr(), 3*time.Minute)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -220,8 +227,10 @@ func (c *Client) Close() error {
|
|||||||
return c.SamConn.Close()
|
return c.SamConn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClient generates an exact copy of the client with the same options
|
// NewClient generates an exact copy of the client with the same options, but
|
||||||
func (c *Client) NewClient() (*Client, error) {
|
// 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(
|
return NewClientFromOptions(
|
||||||
SetHost(c.host),
|
SetHost(c.host),
|
||||||
SetPort(c.port),
|
SetPort(c.port),
|
||||||
@ -242,7 +251,6 @@ func (c *Client) NewClient() (*Client, error) {
|
|||||||
SetCloseIdle(c.closeIdle),
|
SetCloseIdle(c.closeIdle),
|
||||||
SetCloseIdleTime(c.closeIdleTime),
|
SetCloseIdleTime(c.closeIdleTime),
|
||||||
SetCompression(c.compression),
|
SetCompression(c.compression),
|
||||||
setlastaddr(c.lastaddr),
|
setid(id),
|
||||||
setid(c.id),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
22
dial.go
22
dial.go
@ -25,12 +25,10 @@ func (c *Client) DialContext(ctx context.Context, network, addr string) (net.Con
|
|||||||
}()
|
}()
|
||||||
select {
|
select {
|
||||||
case err := <-errCh:
|
case err := <-errCh:
|
||||||
c.Close()
|
|
||||||
return nil, err
|
return nil, err
|
||||||
case conn := <-connCh:
|
case conn := <-connCh:
|
||||||
return conn, nil
|
return conn, nil
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
c.Close()
|
|
||||||
return nil, ctx.Err()
|
return nil, ctx.Err()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -38,16 +36,16 @@ func (c *Client) DialContext(ctx context.Context, network, addr string) (net.Con
|
|||||||
func (c *Client) dialCheck(addr string) (int32, bool) {
|
func (c *Client) dialCheck(addr string) (int32, bool) {
|
||||||
if c.lastaddr == "invalid" {
|
if c.lastaddr == "invalid" {
|
||||||
return c.NewID(), true
|
return c.NewID(), true
|
||||||
} else if addr == "" {
|
// } else if addr == "" {
|
||||||
return c.id, false
|
// return c.id, false
|
||||||
} else if c.lastaddr != addr {
|
} else if c.lastaddr != addr {
|
||||||
return c.NewID(), true
|
return c.NewID(), true
|
||||||
}
|
}
|
||||||
return c.id, false
|
return c.NewID(), false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) Dial(network, addr string) (net.Conn, error) {
|
func (c *Client) Dial(network, addr string) (net.Conn, error) {
|
||||||
return c.DialContext(context.Background(), network, addr)
|
return c.DialContextFree(network, addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dial implements the net.Dial function and can be used for http.Transport
|
// Dial implements the net.Dial function and can be used for http.Transport
|
||||||
@ -60,16 +58,17 @@ func (c *Client) DialContextFree(network, addr string) (net.Conn, error) {
|
|||||||
}
|
}
|
||||||
addr, err := c.Lookup(addr)
|
addr, err := c.Lookup(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Printf("LOOKUP DIALER ERROR %s %s", addr, err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// var test bool
|
// var test bool
|
||||||
c.id, _ = c.dialCheck(addr)
|
//c.id, _ = c.dialCheck(addr)
|
||||||
|
// log.Println("Address indicates we need to dial a new session.")
|
||||||
// if test {
|
// if test {
|
||||||
c.destination, err = c.CreateStreamSession(c.id, c.destination)
|
c.destination, err = c.CreateStreamSession(c.id, c.destination)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.id += 1
|
c, err = c.NewClient(c.id + 1)
|
||||||
c, err = c.NewClient()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -78,15 +77,16 @@ func (c *Client) DialContextFree(network, addr string) (net.Conn, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c, err = c.NewClient()
|
// }
|
||||||
|
c, err = c.NewClient(c.id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
c.lastaddr = addr
|
c.lastaddr = addr
|
||||||
//}
|
|
||||||
err = c.StreamConnect(c.id, addr)
|
err = c.StreamConnect(c.id, addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
//}
|
||||||
return c.SamConn, nil
|
return c.SamConn, nil
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
package goSam
|
package goSam
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
@ -188,4 +186,3 @@ func TestOptionPortInt(t *testing.T) {
|
|||||||
fmt.Printf("\t address64- %s \t", client.Base64())
|
fmt.Printf("\t address64- %s \t", client.Base64())
|
||||||
fmt.Printf("\t address- %s \t", client.Base32())
|
fmt.Printf("\t address- %s \t", client.Base32())
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
@ -82,9 +82,7 @@ func parseReply(line string) (*Reply, error) {
|
|||||||
} else {
|
} else {
|
||||||
kvPair := strings.SplitN(v, "=", 2)
|
kvPair := strings.SplitN(v, "=", 2)
|
||||||
if kvPair != nil {
|
if kvPair != nil {
|
||||||
if len(kvPair) == 1 {
|
if len(kvPair) != 2 {
|
||||||
return nil, fmt.Errorf("Malformed key-value-pair len 1.\n%s\n", kvPair)
|
|
||||||
} else if len(kvPair) != 2 {
|
|
||||||
return nil, fmt.Errorf("Malformed key-value-pair len != 2.\n%s\n", kvPair)
|
return nil, fmt.Errorf("Malformed key-value-pair len != 2.\n%s\n", kvPair)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user