mirror of
https://github.com/go-i2p/goSam.git
synced 2025-06-08 01:09:18 -04:00
22
auth.go
22
auth.go
@ -1,47 +1,33 @@
|
|||||||
package gosam
|
package gosam
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
// SetupAuth sends the AUTH ENABLE command and immediately sets up a new Username and
|
// SetupAuth sends the AUTH ENABLE command and immediately sets up a new Username and
|
||||||
// Password from the arguments
|
// Password from the arguments
|
||||||
func (c *Client) SetupAuth(user, password string) error {
|
func (c *Client) SetupAuth(user, password string) error {
|
||||||
r, err := c.sendCmd("AUTH ENABLE\n")
|
_, err := c.sendCmd("AUTH ENABLE\n")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if r.Topic != "AUTH" {
|
_, err = c.sendCmd("AUTH %s %s\n", user, password)
|
||||||
return fmt.Errorf("SetupAuth Unknown Reply: %+v\n", r)
|
|
||||||
}
|
|
||||||
r, err = c.sendCmd("AUTH %s %s\n", user, password)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if r.Topic != "AUTH" {
|
|
||||||
return fmt.Errorf("SetupAuth Unknown Reply: %+v\n", r)
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TeardownAuth sends the AUTH DISABLE command but does not remove the Username and
|
// TeardownAuth sends the AUTH DISABLE command but does not remove the Username and
|
||||||
// Password from the client PasswordManager
|
// Password from the client PasswordManager
|
||||||
func (c *Client) TeardownAuth() error {
|
func (c *Client) TeardownAuth() error {
|
||||||
r, err := c.sendCmd("AUTH DISABLE\n")
|
_, err := c.sendCmd("AUTH DISABLE\n")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if r.Topic != "AUTH" {
|
|
||||||
return fmt.Errorf("TeardownAuth Unknown Reply: %+v\n", r)
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) RemoveAuthUser(user string) error {
|
func (c *Client) RemoveAuthUser(user string) error {
|
||||||
r, err := c.sendCmd("AUTH REMOVE %s\n", user)
|
_, err := c.sendCmd("AUTH REMOVE %s\n", user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if r.Topic != "AUTH" {
|
|
||||||
return fmt.Errorf("RemoveAuthUser Unknown Reply: %+v\n", r)
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
71
client.go
71
client.go
@ -77,6 +77,8 @@ var SAMsigTypes = []string{
|
|||||||
|
|
||||||
var ValidSAMCommands = []string{
|
var ValidSAMCommands = []string{
|
||||||
"HELLO",
|
"HELLO",
|
||||||
|
"DEST",
|
||||||
|
"NAMING",
|
||||||
"SESSION",
|
"SESSION",
|
||||||
"STREAM",
|
"STREAM",
|
||||||
}
|
}
|
||||||
@ -220,25 +222,34 @@ func (c *Client) samaddr() string {
|
|||||||
|
|
||||||
// send the initial handshake command and check that the reply is ok
|
// send the initial handshake command and check that the reply is ok
|
||||||
func (c *Client) hello() error {
|
func (c *Client) hello() error {
|
||||||
|
var r *Reply
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if c.getUser() == "" {
|
||||||
|
r, err = c.sendCmd("HELLO VERSION MIN=3.%d MAX=3.%d\n", c.sammin, c.sammax)
|
||||||
|
} else if c.getUser() != "" && c.getPass() == "" {
|
||||||
|
r, err = c.sendCmd("HELLO VERSION MIN=3.%d MAX=3.%d %s\n", c.sammin, c.sammax, c.getUser())
|
||||||
|
} else {
|
||||||
|
r, err = c.sendCmd("HELLO VERSION MIN=3.%d MAX=3.%d %s %s\n", c.sammin, c.sammax, c.getUser(), c.getPass())
|
||||||
|
}
|
||||||
|
|
||||||
r, err := c.sendCmd("HELLO VERSION MIN=3.%d MAX=3.%d %s %s\n", c.sammin, c.sammax, c.getUser(), c.getPass())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.Topic != "HELLO" {
|
if !r.IsOk() {
|
||||||
return fmt.Errorf("Client Hello Unknown Reply: %+v\n", r)
|
return fmt.Errorf("handshake did not succeed\nReply:%+v", r)
|
||||||
}
|
|
||||||
|
|
||||||
if r.Pairs["RESULT"] != "OK" {
|
|
||||||
return fmt.Errorf("Handshake did not succeed\nReply:%+v\n", r)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// helper to send one command and parse the reply by sam
|
// helper to send one command and parse the reply by sam
|
||||||
func (c *Client) sendCmd(str string, args ...interface{}) (*Reply, error) {
|
func (c *Client) sendCmd(str string, args ...any) (*Reply, error) {
|
||||||
|
if err := validateCommand(str); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
if _, err := fmt.Fprintf(c.SamConn, str, args...); err != nil {
|
if _, err := fmt.Fprintf(c.SamConn, str, args...); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -248,7 +259,49 @@ func (c *Client) sendCmd(str string, args ...interface{}) (*Reply, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return parseReply(line)
|
r, err := parseReply(line)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.validateReply(str, r); err != nil {
|
||||||
|
return nil, fmt.Errorf("unrecogized reply: %+v\n%v", r, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateCommand(str string) error {
|
||||||
|
topic, _, _ := strings.Cut(str, " ")
|
||||||
|
for _, x := range ValidSAMCommands {
|
||||||
|
if x == topic {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("unsupported sam command %v", topic)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) validateReply(command string, reply *Reply) error {
|
||||||
|
expectedTypesMap := map[string]string{
|
||||||
|
"HELLO": "REPLY",
|
||||||
|
"DEST": "REPLY",
|
||||||
|
"NAMING": "REPLY",
|
||||||
|
"SESSION": "STATUS",
|
||||||
|
"STREAM": "STATUS",
|
||||||
|
}
|
||||||
|
commandTopic, _, _ := strings.Cut(command, " ")
|
||||||
|
|
||||||
|
if commandTopic != reply.Topic {
|
||||||
|
return fmt.Errorf("unrecogized reply topic. expecting: %v, got: %v", commandTopic, reply.Topic)
|
||||||
|
}
|
||||||
|
|
||||||
|
if expectedTypesMap[commandTopic] != reply.Type {
|
||||||
|
return fmt.Errorf("unrecogized reply type. expecting: %v, got: %v", expectedTypesMap[commandTopic], reply.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close the underlying socket to SAM
|
// Close the underlying socket to SAM
|
||||||
|
5
dest.go
5
dest.go
@ -26,7 +26,7 @@ func validateKind(kind string) (string, error) {
|
|||||||
if kint >= 0 && kint <= 7 {
|
if kint >= 0 && kint <= 7 {
|
||||||
return validateKindInner(kind), nil
|
return validateKindInner(kind), nil
|
||||||
}
|
}
|
||||||
return "SIGNATURE_TYPE=7", fmt.Errorf("Invalid sigType: %s", kind)
|
return "SIGNATURE_TYPE=7", fmt.Errorf("invalid sigType: %s", kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a new destination and return the base64 encoded string
|
// Generate a new destination and return the base64 encoded string
|
||||||
@ -46,9 +46,6 @@ func (c *Client) NewDestination(kind ...string) (string, string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
if r.Topic != "DEST" {
|
|
||||||
return "", "", fmt.Errorf("NewDestination Unknown Reply: %+v\n", r)
|
|
||||||
}
|
|
||||||
return r.Pairs["PRIV"], r.Pairs["PUB"], nil
|
return r.Pairs["PRIV"], r.Pairs["PUB"], nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
4
dial.go
4
dial.go
@ -2,7 +2,7 @@ package gosam
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
@ -66,7 +66,7 @@ func (c *Client) DialDatagramContextFree(addr string) (*DatagramConn, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("Datagram support is not finished yet, come back later`")
|
return nil, errors.New("datagram support is not finished yet, come back later")
|
||||||
}
|
}
|
||||||
|
|
||||||
// DialStreamingContextFree is a "Dialer" for "Client-Like" Streaming connections.
|
// DialStreamingContextFree is a "Dialer" for "Client-Like" Streaming connections.
|
||||||
|
12
naming.go
12
naming.go
@ -15,20 +15,14 @@ func (c *Client) Lookup(name string) (string, error) {
|
|||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: move check into sendCmd()
|
if !r.IsOk() {
|
||||||
if r.Topic != "NAMING" || r.Type != "REPLY" {
|
return "", ReplyError{r.GetResult(), r}
|
||||||
return "", fmt.Errorf("Naming Unknown Reply: %s, %s\n", r.Topic, r.Type)
|
|
||||||
}
|
|
||||||
|
|
||||||
result := r.Pairs["RESULT"]
|
|
||||||
if result != "OK" {
|
|
||||||
return "", ReplyError{result, r}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.Pairs["NAME"] != name {
|
if r.Pairs["NAME"] != name {
|
||||||
// somehow different on i2pd
|
// somehow different on i2pd
|
||||||
if r.Pairs["NAME"] != "ME" {
|
if r.Pairs["NAME"] != "ME" {
|
||||||
return "", fmt.Errorf("Lookup() Replyed to another name.\nWanted:%s\nGot: %+v\n", name, r)
|
return "", fmt.Errorf("Lookup() Replyed to another name.\nWanted:%s\nGot: %+v", name, r)
|
||||||
}
|
}
|
||||||
fmt.Fprintln(os.Stderr, "WARNING: Lookup() Replyed to another name. assuming i2pd c++ fluke")
|
fmt.Fprintln(os.Stderr, "WARNING: Lookup() Replyed to another name. assuming i2pd c++ fluke")
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,8 @@ func TestClientLookupInvalid(t *testing.T) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
t.Fatalf("client.Lookup() should return a ReplyError")
|
t.Fatalf("client.Lookup() should return a ReplyError")
|
||||||
}
|
}
|
||||||
if repErr.Result != ResultKeyNotFound {
|
if repErr.Result != ResultKeyNotFound && repErr.Result != ResultInvalidKey {
|
||||||
t.Errorf("client.Lookup() should throw an ResultKeyNotFound error.\nGot:%+v%s%s\n", repErr, "!=", ResultKeyNotFound)
|
t.Errorf("client.Lookup() should either throw an ResultKeyNotFound(i2p) or ResultInvalidKey(i2pd) error.\nGot:%+v%s%s\n", repErr, "!=", ResultKeyNotFound)
|
||||||
}
|
}
|
||||||
if err := client.Close(); err != nil {
|
if err := client.Close(); err != nil {
|
||||||
t.Fatalf("client.Close() Error: %q\n", err)
|
t.Fatalf("client.Close() Error: %q\n", err)
|
||||||
|
65
options.go
65
options.go
@ -1,6 +1,7 @@
|
|||||||
package gosam
|
package gosam
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -21,11 +22,11 @@ func SetAddr(s ...string) func(*Client) error {
|
|||||||
c.port = split[1]
|
c.port = split[1]
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Invalid port")
|
return errors.New("invalid port")
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Invalid port; non-number")
|
return errors.New("invalid port; non-number")
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Invalid address; use host:port %s", split)
|
return fmt.Errorf("invalid address; use host:port %s", split)
|
||||||
} else if len(s) == 2 {
|
} else if len(s) == 2 {
|
||||||
if i, err := strconv.Atoi(s[1]); err == nil {
|
if i, err := strconv.Atoi(s[1]); err == nil {
|
||||||
if i < 65536 {
|
if i < 65536 {
|
||||||
@ -33,11 +34,11 @@ func SetAddr(s ...string) func(*Client) error {
|
|||||||
c.port = s[1]
|
c.port = s[1]
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Invalid port")
|
return errors.New("invalid port")
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Invalid port; non-number")
|
return errors.New("invalid port; non-number")
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("Invalid address")
|
return errors.New("invalid address")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,7 +51,7 @@ func SetAddrMixed(s string, i int) func(*Client) error {
|
|||||||
c.port = strconv.Itoa(i)
|
c.port = strconv.Itoa(i)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Invalid port")
|
return errors.New("invalid port")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,10 +82,10 @@ func SetPass(s string) func(*Client) error {
|
|||||||
func SetSAMMinVersion(i int) func(*Client) error {
|
func SetSAMMinVersion(i int) func(*Client) error {
|
||||||
return func(c *Client) error {
|
return func(c *Client) error {
|
||||||
if i < 0 {
|
if i < 0 {
|
||||||
return fmt.Errorf("SAM version must be greater than or equal to 0")
|
return errors.New("SAM version must be greater than or equal to 0")
|
||||||
}
|
}
|
||||||
if i > 3 {
|
if i > 3 {
|
||||||
return fmt.Errorf("SAM version must be less than or equal to 3")
|
return errors.New("SAM version must be less than or equal to 3")
|
||||||
}
|
}
|
||||||
c.sammin = i
|
c.sammin = i
|
||||||
return nil
|
return nil
|
||||||
@ -94,10 +95,10 @@ func SetSAMMinVersion(i int) func(*Client) error {
|
|||||||
func SetSAMMaxVersion(i int) func(*Client) error {
|
func SetSAMMaxVersion(i int) func(*Client) error {
|
||||||
return func(c *Client) error {
|
return func(c *Client) error {
|
||||||
if i < 0 {
|
if i < 0 {
|
||||||
return fmt.Errorf("SAM version must be greater than or equal to 0")
|
return errors.New("SAM version must be greater than or equal to 0")
|
||||||
}
|
}
|
||||||
if i > 3 {
|
if i > 3 {
|
||||||
return fmt.Errorf("SAM version must be less than or equal to 3")
|
return errors.New("SAM version must be less than or equal to 3")
|
||||||
}
|
}
|
||||||
c.sammin = i
|
c.sammin = i
|
||||||
return nil
|
return nil
|
||||||
@ -125,13 +126,13 @@ func SetPort(s string) func(*Client) error {
|
|||||||
return func(c *Client) error {
|
return func(c *Client) error {
|
||||||
port, err := strconv.Atoi(s)
|
port, err := strconv.Atoi(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Invalid port; non-number")
|
return errors.New("invalid port; non-number")
|
||||||
}
|
}
|
||||||
if port < 65536 && port > -1 {
|
if port < 65536 && port > -1 {
|
||||||
c.port = s
|
c.port = s
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Invalid port")
|
return errors.New("invalid port")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +143,7 @@ func SetPortInt(i int) func(*Client) error {
|
|||||||
c.port = strconv.Itoa(i)
|
c.port = strconv.Itoa(i)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Invalid port")
|
return errors.New("invalid port")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,13 +152,13 @@ func SetFromPort(s string) func(*Client) error {
|
|||||||
return func(c *Client) error {
|
return func(c *Client) error {
|
||||||
port, err := strconv.Atoi(s)
|
port, err := strconv.Atoi(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Invalid port; non-number")
|
return errors.New("invalid port; non-number")
|
||||||
}
|
}
|
||||||
if port < 65536 && port > -1 {
|
if port < 65536 && port > -1 {
|
||||||
c.fromport = s
|
c.fromport = s
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Invalid port")
|
return errors.New("invalid port")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,7 +169,7 @@ func SetFromPortInt(i int) func(*Client) error {
|
|||||||
c.fromport = strconv.Itoa(i)
|
c.fromport = strconv.Itoa(i)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Invalid port")
|
return errors.New("invalid port")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,13 +178,13 @@ func SetToPort(s string) func(*Client) error {
|
|||||||
return func(c *Client) error {
|
return func(c *Client) error {
|
||||||
port, err := strconv.Atoi(s)
|
port, err := strconv.Atoi(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Invalid port; non-number")
|
return errors.New("invalid port; non-number")
|
||||||
}
|
}
|
||||||
if port < 65536 && port > -1 {
|
if port < 65536 && port > -1 {
|
||||||
c.toport = s
|
c.toport = s
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Invalid port")
|
return errors.New("invalid port")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,7 +195,7 @@ func SetToPortInt(i int) func(*Client) error {
|
|||||||
c.fromport = strconv.Itoa(i)
|
c.fromport = strconv.Itoa(i)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Invalid port")
|
return errors.New("invalid port")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,7 +215,7 @@ func SetInLength(u uint) func(*Client) error {
|
|||||||
c.inLength = u
|
c.inLength = u
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Invalid inbound tunnel length")
|
return errors.New("invalid inbound tunnel length")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,7 +226,7 @@ func SetOutLength(u uint) func(*Client) error {
|
|||||||
c.outLength = u
|
c.outLength = u
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Invalid outbound tunnel length")
|
return errors.New("invalid outbound tunnel length")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,7 +237,7 @@ func SetInVariance(i int) func(*Client) error {
|
|||||||
c.inVariance = i
|
c.inVariance = i
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Invalid inbound tunnel length")
|
return errors.New("invalid inbound tunnel length")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +248,7 @@ func SetOutVariance(i int) func(*Client) error {
|
|||||||
c.outVariance = i
|
c.outVariance = i
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Invalid outbound tunnel variance")
|
return errors.New("invalid outbound tunnel variance")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,7 +259,7 @@ func SetInQuantity(u uint) func(*Client) error {
|
|||||||
c.inQuantity = u
|
c.inQuantity = u
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Invalid inbound tunnel quantity")
|
return errors.New("invalid inbound tunnel quantity")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,7 +270,7 @@ func SetOutQuantity(u uint) func(*Client) error {
|
|||||||
c.outQuantity = u
|
c.outQuantity = u
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Invalid outbound tunnel quantity")
|
return errors.New("invalid outbound tunnel quantity")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,7 +281,7 @@ func SetInBackups(u uint) func(*Client) error {
|
|||||||
c.inBackups = u
|
c.inBackups = u
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Invalid inbound tunnel backup quantity")
|
return errors.New("invalid inbound tunnel backup quantity")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,7 +292,7 @@ func SetOutBackups(u uint) func(*Client) error {
|
|||||||
c.outBackups = u
|
c.outBackups = u
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Invalid outbound tunnel backup quantity")
|
return errors.New("invalid outbound tunnel backup quantity")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,7 +336,7 @@ func SetReduceIdleTime(u uint) func(*Client) error {
|
|||||||
c.reduceIdleTime = u
|
c.reduceIdleTime = u
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Invalid reduce idle time %v", u)
|
return fmt.Errorf("invalid reduce idle time %v", u)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,7 +347,7 @@ func SetReduceIdleQuantity(u uint) func(*Client) error {
|
|||||||
c.reduceIdleQuantity = u
|
c.reduceIdleQuantity = u
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Invalid reduced tunnel quantity %v", u)
|
return fmt.Errorf("invalid reduced tunnel quantity %v", u)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,7 +366,7 @@ func SetCloseIdleTime(u uint) func(*Client) error {
|
|||||||
c.closeIdleTime = u
|
c.closeIdleTime = u
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Invalid close idle time %v", u)
|
return fmt.Errorf("invalid close idle time %v", u)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,7 +402,7 @@ func SetSignatureType(s string) func(*Client) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Invalid signature type specified at construction time")
|
return errors.New("invalid signature type specified at construction time")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,11 +38,26 @@ type Reply struct {
|
|||||||
Pairs map[string]string
|
Pairs map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Reply) IsOk() bool {
|
||||||
|
return r.Pairs["RESULT"] == ResultOk
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Reply) GetResult() string {
|
||||||
|
result, ok := r.Pairs["RESULT"]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
// TODO Add some debug output
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
func parseReply(line string) (*Reply, error) {
|
func parseReply(line string) (*Reply, error) {
|
||||||
line = strings.TrimSpace(line)
|
line = strings.TrimSpace(line)
|
||||||
parts := strings.Split(line, " ")
|
parts := strings.Split(line, " ")
|
||||||
if len(parts) < 3 {
|
if len(parts) < 3 {
|
||||||
return nil, fmt.Errorf("Malformed Reply.\n%s\n", line)
|
return nil, fmt.Errorf("malformed Reply.\n%s", line)
|
||||||
}
|
}
|
||||||
preParseReply := func() []string {
|
preParseReply := func() []string {
|
||||||
val := ""
|
val := ""
|
||||||
@ -83,7 +98,7 @@ func parseReply(line string) (*Reply, error) {
|
|||||||
kvPair := strings.SplitN(v, "=", 2)
|
kvPair := strings.SplitN(v, "=", 2)
|
||||||
if kvPair != nil {
|
if kvPair != nil {
|
||||||
if len(kvPair) != 2 {
|
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", kvPair)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
r.Pairs[kvPair[0]] = kvPair[len(kvPair)-1]
|
r.Pairs[kvPair[0]] = kvPair[len(kvPair)-1]
|
||||||
|
19
sessions.go
19
sessions.go
@ -1,16 +1,5 @@
|
|||||||
package gosam
|
package gosam
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
// "math"
|
|
||||||
"math/rand"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
rand.Seed(time.Now().UnixNano())
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateSession creates a new Session of type style, with an optional destination.
|
// CreateSession creates a new Session of type style, with an optional destination.
|
||||||
// an empty destination is interpreted as "TRANSIENT"
|
// an empty destination is interpreted as "TRANSIENT"
|
||||||
// Returns the destination for the new Client or an error.
|
// Returns the destination for the new Client or an error.
|
||||||
@ -33,13 +22,7 @@ func (c *Client) CreateSession(style, dest string) (string, error) {
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: move check into sendCmd()
|
if !r.IsOk() {
|
||||||
if r.Topic != "SESSION" || r.Type != "STATUS" {
|
|
||||||
return "", fmt.Errorf("Session Unknown Reply: %+v\n", r)
|
|
||||||
}
|
|
||||||
|
|
||||||
result := r.Pairs["RESULT"]
|
|
||||||
if result != "OK" {
|
|
||||||
return "", ReplyError{ResultKeyNotFound, r}
|
return "", ReplyError{ResultKeyNotFound, r}
|
||||||
}
|
}
|
||||||
c.destination = r.Pairs["DESTINATION"]
|
c.destination = r.Pairs["DESTINATION"]
|
||||||
|
24
stream.go
24
stream.go
@ -1,9 +1,5 @@
|
|||||||
package gosam
|
package gosam
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// StreamConnect asks SAM for a TCP-Like connection to dest, has to be called on a new Client
|
// StreamConnect asks SAM for a TCP-Like connection to dest, has to be called on a new Client
|
||||||
func (c *Client) StreamConnect(dest string) error {
|
func (c *Client) StreamConnect(dest string) error {
|
||||||
if dest == "" {
|
if dest == "" {
|
||||||
@ -14,14 +10,8 @@ func (c *Client) StreamConnect(dest string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: move check into sendCmd()
|
if !r.IsOk() {
|
||||||
if r.Topic != "STREAM" || r.Type != "STATUS" {
|
return ReplyError{r.GetResult(), r}
|
||||||
return fmt.Errorf("Stream Connect Unknown Reply: %+v\n", r)
|
|
||||||
}
|
|
||||||
|
|
||||||
result := r.Pairs["RESULT"]
|
|
||||||
if result != "OK" {
|
|
||||||
return ReplyError{result, r}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -34,14 +24,8 @@ func (c *Client) StreamAccept() (*Reply, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: move check into sendCmd()
|
if !r.IsOk() {
|
||||||
if r.Topic != "STREAM" || r.Type != "STATUS" {
|
return nil, ReplyError{r.GetResult(), r}
|
||||||
return nil, fmt.Errorf("Stream Accept Unknown Reply: %+v\n", r)
|
|
||||||
}
|
|
||||||
|
|
||||||
result := r.Pairs["RESULT"]
|
|
||||||
if result != "OK" {
|
|
||||||
return nil, ReplyError{result, r}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return r, nil
|
return r, nil
|
||||||
|
Reference in New Issue
Block a user