Documentation ¶
Overview ¶
Package hmsg implements reading and writing of length- and checksum-prefixed messages.
Index ¶
- func IsVerifyError(err error) bool
- func MaxMessageSize(payloadSize int64, hashfn HashFunc) int64
- func NullHash() hash.Hash
- type HashFunc
- type Messenger
- func (m *Messenger) HashFunc() HashFunc
- func (m *Messenger) MaxMessageSize() int64
- func (m *Messenger) MaxPayloadSize() int64
- func (m *Messenger) MsgBytes(p []byte) ([]byte, error)
- func (m *Messenger) ReadMsg(r io.Reader) ([]byte, error)
- func (m *Messenger) ReadMsgBytes(p []byte) ([]byte, error)
- func (m *Messenger) ReadMsgTo(p []byte, r io.Reader) ([]byte, error)
- func (m *Messenger) WriteMsg(w io.Writer, p []byte) error
- type VerifyError
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func IsVerifyError ¶
IsVerifyError returns whether err is a *VerifyError.
func MaxMessageSize ¶
MaxMessageSize returns the maximum message size needed to contain a payload of payloadSize, checksum for hashfn, and the length prefix of the message.
Types ¶
type HashFunc ¶
HashFunc is a function that returns a new hash.Hash for use in a Messenger. Returned hashes are not reused.
type Messenger ¶
type Messenger struct {
// contains filtered or unexported fields
}
Messenger reads and writes messages with length and checksum prefixes.
A Messenger is safe to use across multiple goroutines and does not keep any state.
Example ¶
package main import ( "bytes" "crypto/sha1" "fmt" "go.spiff.io/hmsg" ) func main() { // Allocate a new Messenger for sending messages up to 1000 bytes long. // // For this, we'll use HMAC-SHA1 to verify messages, but you can also // use plain MD5, CRC32, SHA1, or other hashes. m, err := hmsg.NewMessenger(1000, hmsg.HMAC("super-secret-key", sha1.New)) if err != nil { panic(fmt.Sprint("Error creating messenger: ", err)) } const message = "Hello, World" // Create a buffer to write a message -- in practice, this might be // a TCP connection or something similar. buf := &bytes.Buffer{} // Write a message to the buffer. The message includes its length and // checksum, which is used to verify the message when we read it. if err := m.WriteMsg(buf, []byte(message)); err != nil { panic(fmt.Sprint("Error writing message: ", err)) } // Read the message. If it had been tampered with, ReadMsg would return // a *VerifyError. received, err := m.ReadMsg(buf) if err != nil { panic(fmt.Sprint("Error receiving message: ", err)) } fmt.Printf("Received message: %q\n", string(received)) }
Output: Received message: "Hello, World"
func NewMessenger ¶
NewMessenger allocates a new Messenger for reading and writing length- and checksum-prefixed messages.
maxMsgSize specifies the maximum size of a message in bytes, and must be greater than the minimum size needed to contain a message length prefix for maxMsgSize and its checksum. If maxMsgSize would be invalid, or the hash function does not return a valid message size (or is nil), NewMessenger returns an error.
If maxMsgSize is zero (or less), the upper limit for message size is math.MaxInt64. The upper limit may change depending on the target system, so it's recommended that you specify your own size limit.
func (*Messenger) MaxMessageSize ¶
MaxMessageSize returns the maximum message size. Message size includes the length prefix and checksum size.
If the Messenger was not given an explicit message size, MaxMessageSize returns a reasonable maximum for the target system (currently math.MaxInt64, but this may change).
func (*Messenger) MaxPayloadSize ¶
MaxPayloadSize returns the maximum payload size. This is the size of the largest payload that can be sent. The result of MaxPayloadSize is always less than or equal to MaxMessageSize.
func (*Messenger) MsgBytes ¶
MsgBytes is a convenience function to encode a message for p and return a new byte slice containing the encoded message. See WriteMsg for more details.
func (*Messenger) ReadMsg ¶
ReadMsg reads length, checksum, and payload from r. This function is identical to ReadMsgTo, except that it will always allocate a new byte slice for the message. See ReadMsgTo for more detail.
func (*Messenger) ReadMsgBytes ¶
ReadMsgBytes is a convenience function to read a message from the payload p. It returns a new byte slice for the message, if successfully read. See ReadMsgTo formore detail.
func (*Messenger) ReadMsgTo ¶
ReadMsgTo reads length, checksum, and payload from r and, if the message is valid, stores the payload in the slice p and returns the payload.
If the checksum of the payload does not match when filtered through Messenger's hash function, it returns a *VerifyError. This is to prevent acceptance of corrupt, spoofed, or otherwise invalid messages (depending on the checksum).
If p is not large enough to accommodate the message payload, a large enough byte slice is allocated to hold it.
Too-small and too-large messages will also return errors. All other errors arise from reading from r.
func (*Messenger) WriteMsg ¶
WriteMsg writes the payload, p, prefixed by its length and checksum, to the writer w.
If the total length of the message (length prefix, checksum, and payload p) exceeds the Messenger's maximum message size, then the message is not written and WriteMsg returns an error.
All other errors arise from writing to w.
type VerifyError ¶
VerifyError is returned when a receive's message's checksum does not match its contents.