1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
package network // import "collectd.org/network"
import (
"context"
"net"
"collectd.org/api"
)
// ClientOptions holds configuration options for Client.
type ClientOptions struct {
// SecurityLevel determines whether data is signed, encrypted or sent
// in plain text.
SecurityLevel SecurityLevel
// Username and password for the "Sign" and "Encrypt" security levels.
Username, Password string
// Size of the send buffer. When zero, DefaultBufferSize is used.
BufferSize int
}
// Client is a connection to a collectd server. It implements the
// api.Writer interface.
type Client struct {
udp net.Conn
buffer *Buffer
opts ClientOptions
}
// Dial connects to the collectd server at address. "address" must be a network
// address accepted by net.Dial().
func Dial(address string, opts ClientOptions) (*Client, error) {
c, err := net.Dial("udp", address)
if err != nil {
return nil, err
}
b := NewBuffer(opts.BufferSize)
if opts.SecurityLevel == Sign {
b.Sign(opts.Username, opts.Password)
} else if opts.SecurityLevel == Encrypt {
b.Encrypt(opts.Username, opts.Password)
}
return &Client{
udp: c,
buffer: b,
opts: opts,
}, nil
}
// Write adds a ValueList to the internal buffer. Data is only written to
// the network when the buffer is full.
func (c *Client) Write(ctx context.Context, vl *api.ValueList) error {
if err := c.buffer.Write(ctx, vl); err != ErrNotEnoughSpace {
return err
}
if err := c.Flush(); err != nil {
return err
}
return c.buffer.Write(ctx, vl)
}
// Flush writes the contents of the underlying buffer to the network
// immediately.
func (c *Client) Flush() error {
_, err := c.buffer.WriteTo(c.udp)
return err
}
// Close writes remaining data to the network and closes the socket. You must
// not use "c" after this call.
func (c *Client) Close() error {
if err := c.Flush(); err != nil {
return err
}
if err := c.udp.Close(); err != nil {
return err
}
c.buffer = nil
return nil
}
|