2014-02-09 18:40:51 +01:00
|
|
|
package goSam
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
|
|
|
"fmt"
|
2014-02-10 19:27:24 +01:00
|
|
|
"net"
|
2015-03-25 21:37:41 +01:00
|
|
|
|
|
|
|
"github.com/cryptix/go/debug"
|
2014-02-09 18:40:51 +01:00
|
|
|
)
|
|
|
|
|
2014-02-11 14:48:13 +01:00
|
|
|
// A Client represents a single Connection to the SAM bridge
|
2014-02-09 18:40:51 +01:00
|
|
|
type Client struct {
|
2018-07-16 02:49:03 -04:00
|
|
|
host string
|
|
|
|
port string
|
|
|
|
|
2014-02-11 14:08:52 +01:00
|
|
|
SamConn net.Conn
|
2015-03-25 21:37:41 +01:00
|
|
|
rd *bufio.Reader
|
2018-07-16 02:49:03 -04:00
|
|
|
|
|
|
|
inLength uint
|
|
|
|
inVariance int
|
|
|
|
inQuantity uint
|
|
|
|
inBackups uint
|
|
|
|
|
|
|
|
outLength uint
|
|
|
|
outVariance int
|
|
|
|
outQuantity uint
|
|
|
|
outBackups uint
|
|
|
|
|
|
|
|
dontPublishLease bool
|
|
|
|
encryptLease bool
|
|
|
|
|
|
|
|
debug bool
|
2014-02-09 18:40:51 +01:00
|
|
|
}
|
|
|
|
|
2014-02-14 12:05:13 +01:00
|
|
|
// NewDefaultClient creates a new client, connecting to the default host:port at localhost:7656
|
2014-02-10 19:27:24 +01:00
|
|
|
func NewDefaultClient() (*Client, error) {
|
|
|
|
return NewClient("localhost:7656")
|
|
|
|
}
|
|
|
|
|
2014-02-14 12:05:13 +01:00
|
|
|
// NewClient creates a new client, connecting to a specified port
|
2014-02-10 19:27:24 +01:00
|
|
|
func NewClient(addr string) (*Client, error) {
|
2018-07-16 02:49:03 -04:00
|
|
|
return NewClientFromOptions(SetAddr(addr))
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewClientFromOptions creates a new client, connecting to a specified port
|
|
|
|
func NewClientFromOptions(opts ...func(*Client) error) (*Client, error) {
|
|
|
|
var c Client
|
|
|
|
c.host = "127.0.0.1"
|
|
|
|
c.port = "7656"
|
|
|
|
c.inLength = 3
|
|
|
|
c.inVariance = 0
|
|
|
|
c.inQuantity = 4
|
|
|
|
c.inBackups = 2
|
|
|
|
c.outLength = 3
|
|
|
|
c.outVariance = 0
|
|
|
|
c.outQuantity = 4
|
|
|
|
c.outBackups = 2
|
|
|
|
c.dontPublishLease = true
|
|
|
|
c.encryptLease = false
|
|
|
|
c.debug = false
|
|
|
|
for _, o := range opts {
|
|
|
|
if err := o(&c); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
conn, err := net.Dial("tcp", c.samaddr())
|
2014-02-10 19:27:24 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2018-07-16 02:49:03 -04:00
|
|
|
if c.debug {
|
2015-03-25 21:37:41 +01:00
|
|
|
conn = debug.WrapConn(conn)
|
|
|
|
}
|
2018-07-16 02:49:03 -04:00
|
|
|
c.SamConn = conn
|
|
|
|
c.rd = bufio.NewReader(conn)
|
|
|
|
return &c, c.hello()
|
|
|
|
}
|
|
|
|
|
|
|
|
//return the combined host:port of the SAM bridge
|
|
|
|
func (c *Client) samaddr() string {
|
|
|
|
return fmt.Sprintf("%s:%s", c.host, c.port)
|
2014-02-09 18:40:51 +01:00
|
|
|
}
|
|
|
|
|
2014-02-11 13:10:24 +01:00
|
|
|
// send the initial handshake command and check that the reply is ok
|
2015-03-25 22:03:05 +01:00
|
|
|
func (c *Client) hello() error {
|
2018-07-16 02:49:03 -04:00
|
|
|
r, err := c.sendCmd("HELLO VERSION MIN=3.0 MAX=3.0\n", c.allOptions())
|
2014-02-11 13:10:24 +01:00
|
|
|
if err != nil {
|
2014-02-09 18:40:51 +01:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2014-02-11 13:10:24 +01:00
|
|
|
if r.Topic != "HELLO" {
|
|
|
|
return fmt.Errorf("Unknown Reply: %+v\n", r)
|
|
|
|
}
|
2014-02-09 18:40:51 +01:00
|
|
|
|
2014-02-11 14:08:52 +01:00
|
|
|
if r.Pairs["RESULT"] != "OK" || r.Pairs["VERSION"] != "3.0" {
|
2014-02-11 13:10:24 +01:00
|
|
|
return fmt.Errorf("Handshake did not succeed\nReply:%+v\n", r)
|
2014-02-09 18:40:51 +01:00
|
|
|
}
|
2014-02-11 13:10:24 +01:00
|
|
|
|
2014-02-09 18:40:51 +01:00
|
|
|
return nil
|
2014-02-11 13:11:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// helper to send one command and parse the reply by sam
|
2015-03-25 22:03:05 +01:00
|
|
|
func (c *Client) sendCmd(str string, args ...interface{}) (*Reply, error) {
|
|
|
|
if _, err := fmt.Fprintf(c.SamConn, str, args...); err != nil {
|
|
|
|
return nil, err
|
2014-02-11 13:11:26 +01:00
|
|
|
}
|
|
|
|
|
2015-03-25 21:37:41 +01:00
|
|
|
line, err := c.rd.ReadString('\n')
|
2014-02-11 13:11:26 +01:00
|
|
|
if err != nil {
|
2015-03-25 22:03:05 +01:00
|
|
|
return nil, err
|
2014-02-11 13:11:26 +01:00
|
|
|
}
|
2014-02-11 13:10:24 +01:00
|
|
|
|
2015-03-25 21:37:41 +01:00
|
|
|
return parseReply(line)
|
2014-02-09 18:40:51 +01:00
|
|
|
}
|
|
|
|
|
2014-02-11 14:48:13 +01:00
|
|
|
// Close the underlying socket to SAM
|
2014-02-09 18:40:51 +01:00
|
|
|
func (c *Client) Close() error {
|
2015-03-25 22:03:05 +01:00
|
|
|
c.rd = nil
|
2014-02-11 14:08:52 +01:00
|
|
|
return c.SamConn.Close()
|
2014-02-09 18:40:51 +01:00
|
|
|
}
|