|
|
@ -20,8 +20,8 @@ const ( |
|
|
|
maxDomainPartSize = (255 + 1) |
|
|
|
) |
|
|
|
|
|
|
|
// MessageHeader is the header of an imsg frame (struct imsg_hdr)
|
|
|
|
type MessageHeader struct { |
|
|
|
// messageHeader is the header of an imsg frame (struct imsg_hdr)
|
|
|
|
type messageHeader struct { |
|
|
|
Type uint32 |
|
|
|
Len uint16 |
|
|
|
Flags uint16 |
|
|
@ -29,9 +29,9 @@ type MessageHeader struct { |
|
|
|
PID uint32 |
|
|
|
} |
|
|
|
|
|
|
|
// Message implements OpenBSD imsg
|
|
|
|
type Message struct { |
|
|
|
MessageHeader |
|
|
|
// message implements OpenBSD imsg
|
|
|
|
type message struct { |
|
|
|
messageHeader |
|
|
|
Data []byte |
|
|
|
|
|
|
|
// rpos is the read position in the current Data
|
|
|
@ -41,7 +41,7 @@ type Message struct { |
|
|
|
buf []byte |
|
|
|
} |
|
|
|
|
|
|
|
func (m *Message) reset() { |
|
|
|
func (m *message) reset() { |
|
|
|
m.Type = 0 |
|
|
|
m.Len = 0 |
|
|
|
m.Flags = 0 |
|
|
@ -54,7 +54,7 @@ func (m *Message) reset() { |
|
|
|
|
|
|
|
// ReadFrom reads a message from the specified net.Conn, parses the header and
|
|
|
|
// reads the data payload.
|
|
|
|
func (m *Message) ReadFrom(c net.Conn) error { |
|
|
|
func (m *message) ReadFrom(c net.Conn) error { |
|
|
|
m.reset() |
|
|
|
|
|
|
|
head := make([]byte, imsgHeaderSize) |
|
|
@ -63,12 +63,12 @@ func (m *Message) ReadFrom(c net.Conn) error { |
|
|
|
} |
|
|
|
|
|
|
|
r := bytes.NewBuffer(head) |
|
|
|
if err := binary.Read(r, binary.LittleEndian, &m.MessageHeader); err != nil { |
|
|
|
if err := binary.Read(r, binary.LittleEndian, &m.messageHeader); err != nil { |
|
|
|
return err |
|
|
|
} |
|
|
|
debugf("imsg header: %+v\n", m.MessageHeader) |
|
|
|
debugf("imsg header: %+v\n", m.messageHeader) |
|
|
|
|
|
|
|
data := make([]byte, m.MessageHeader.Len-imsgHeaderSize) |
|
|
|
data := make([]byte, m.messageHeader.Len-imsgHeaderSize) |
|
|
|
if _, err := c.Read(data); err != nil { |
|
|
|
return err |
|
|
|
} |
|
|
@ -78,13 +78,13 @@ func (m *Message) ReadFrom(c net.Conn) error { |
|
|
|
return nil |
|
|
|
} |
|
|
|
|
|
|
|
// WriteTo marshals the Message to wire format and sends it to the net.Conn
|
|
|
|
func (m *Message) WriteTo(c net.Conn) error { |
|
|
|
// WriteTo marshals the message to wire format and sends it to the net.Conn
|
|
|
|
func (m *message) WriteTo(c net.Conn) error { |
|
|
|
m.Len = uint16(len(m.Data)) + imsgHeaderSize |
|
|
|
|
|
|
|
buf := new(bytes.Buffer) |
|
|
|
debugf("imsg header: %+v\n", m.MessageHeader) |
|
|
|
if err := binary.Write(buf, binary.LittleEndian, &m.MessageHeader); err != nil { |
|
|
|
debugf("imsg header: %+v\n", m.messageHeader) |
|
|
|
if err := binary.Write(buf, binary.LittleEndian, &m.messageHeader); err != nil { |
|
|
|
return err |
|
|
|
} |
|
|
|
buf.Write(m.Data) |
|
|
@ -94,7 +94,7 @@ func (m *Message) WriteTo(c net.Conn) error { |
|
|
|
return err |
|
|
|
} |
|
|
|
|
|
|
|
func (m *Message) GetInt() (int, error) { |
|
|
|
func (m *message) GetInt() (int, error) { |
|
|
|
if m.rpos+4 > len(m.Data) { |
|
|
|
return 0, io.ErrShortBuffer |
|
|
|
} |
|
|
@ -103,7 +103,7 @@ func (m *Message) GetInt() (int, error) { |
|
|
|
return int(i), nil |
|
|
|
} |
|
|
|
|
|
|
|
func (m *Message) GetUint32() (uint32, error) { |
|
|
|
func (m *message) GetUint32() (uint32, error) { |
|
|
|
if m.rpos+4 > len(m.Data) { |
|
|
|
return 0, io.ErrShortBuffer |
|
|
|
} |
|
|
@ -112,7 +112,7 @@ func (m *Message) GetUint32() (uint32, error) { |
|
|
|
return u, nil |
|
|
|
} |
|
|
|
|
|
|
|
func (m *Message) GetSize() (uint64, error) { |
|
|
|
func (m *message) GetSize() (uint64, error) { |
|
|
|
if m.rpos+8 > len(m.Data) { |
|
|
|
return 0, io.ErrShortBuffer |
|
|
|
} |
|
|
@ -121,7 +121,7 @@ func (m *Message) GetSize() (uint64, error) { |
|
|
|
return u, nil |
|
|
|
} |
|
|
|
|
|
|
|
func (m *Message) GetString() (string, error) { |
|
|
|
func (m *message) GetString() (string, error) { |
|
|
|
o := bytes.IndexByte(m.Data[m.rpos:], 0) |
|
|
|
if o < 0 { |
|
|
|
return "", errors.New("imsg: string not NULL-terminated") |
|
|
@ -132,7 +132,7 @@ func (m *Message) GetString() (string, error) { |
|
|
|
return s, nil |
|
|
|
} |
|
|
|
|
|
|
|
func (m *Message) GetID() (uint64, error) { |
|
|
|
func (m *message) GetID() (uint64, error) { |
|
|
|
if m.rpos+8 > len(m.Data) { |
|
|
|
return 0, io.ErrShortBuffer |
|
|
|
} |
|
|
@ -174,7 +174,7 @@ func (sa Sockaddr) String() string { |
|
|
|
return fmt.Sprintf("%s:%d", sa.IP(), sa.Port()) |
|
|
|
} |
|
|
|
|
|
|
|
func (m *Message) GetSockaddr() (net.Addr, error) { |
|
|
|
func (m *message) GetSockaddr() (net.Addr, error) { |
|
|
|
s, err := m.GetSize() |
|
|
|
if err != nil { |
|
|
|
return nil, err |
|
|
@ -190,7 +190,7 @@ func (m *Message) GetSockaddr() (net.Addr, error) { |
|
|
|
return a, nil |
|
|
|
} |
|
|
|
|
|
|
|
func (m *Message) GetMailaddr() (user, domain string, err error) { |
|
|
|
func (m *message) GetMailaddr() (user, domain string, err error) { |
|
|
|
var buf [maxLocalPartSize + maxDomainPartSize]byte |
|
|
|
if maxLocalPartSize+maxDomainPartSize > len(m.Data[m.rpos:]) { |
|
|
|
return "", "", io.ErrShortBuffer |
|
|
@ -202,7 +202,7 @@ func (m *Message) GetMailaddr() (user, domain string, err error) { |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
func (m *Message) GetType(t uint8) error { |
|
|
|
func (m *message) GetType(t uint8) error { |
|
|
|
if m.rpos >= len(m.Data) { |
|
|
|
return io.ErrShortBuffer |
|
|
|
} |
|
|
@ -210,107 +210,107 @@ func (m *Message) GetType(t uint8) error { |
|
|
|
b := m.Data[m.rpos] |
|
|
|
m.rpos++ |
|
|
|
if b != t { |
|
|
|
return MProcTypeErr{t, b} |
|
|
|
return mprocTypeErr{t, b} |
|
|
|
} |
|
|
|
return nil |
|
|
|
} |
|
|
|
|
|
|
|
func (m *Message) GetTypeInt() (int, error) { |
|
|
|
if err := m.GetType(M_INT); err != nil { |
|
|
|
func (m *message) GetTypeInt() (int, error) { |
|
|
|
if err := m.GetType(mINT); err != nil { |
|
|
|
return 0, err |
|
|
|
} |
|
|
|
return m.GetInt() |
|
|
|
} |
|
|
|
|
|
|
|
func (m *Message) GetTypeUint32() (uint32, error) { |
|
|
|
if err := m.GetType(M_UINT32); err != nil { |
|
|
|
func (m *message) GetTypeUint32() (uint32, error) { |
|
|
|
if err := m.GetType(mUINT32); err != nil { |
|
|
|
return 0, err |
|
|
|
} |
|
|
|
return m.GetUint32() |
|
|
|
} |
|
|
|
|
|
|
|
func (m *Message) GetTypeSize() (uint64, error) { |
|
|
|
if err := m.GetType(M_SIZET); err != nil { |
|
|
|
func (m *message) GetTypeSize() (uint64, error) { |
|
|
|
if err := m.GetType(mSIZET); err != nil { |
|
|
|
return 0, err |
|
|
|
} |
|
|
|
return m.GetSize() |
|
|
|
} |
|
|
|
|
|
|
|
func (m *Message) GetTypeString() (string, error) { |
|
|
|
if err := m.GetType(M_STRING); err != nil { |
|
|
|
func (m *message) GetTypeString() (string, error) { |
|
|
|
if err := m.GetType(mSTRING); err != nil { |
|
|
|
return "", err |
|
|
|
} |
|
|
|
return m.GetString() |
|
|
|
} |
|
|
|
|
|
|
|
func (m *Message) GetTypeID() (uint64, error) { |
|
|
|
if err := m.GetType(M_ID); err != nil { |
|
|
|
func (m *message) GetTypeID() (uint64, error) { |
|
|
|
if err := m.GetType(mID); err != nil { |
|
|
|
return 0, err |
|
|
|
} |
|
|
|
return m.GetID() |
|
|
|
} |
|
|
|
|
|
|
|
func (m *Message) GetTypeSockaddr() (net.Addr, error) { |
|
|
|
if err := m.GetType(M_SOCKADDR); err != nil { |
|
|
|
func (m *message) GetTypeSockaddr() (net.Addr, error) { |
|
|
|
if err := m.GetType(mSOCKADDR); err != nil { |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
return m.GetSockaddr() |
|
|
|
} |
|
|
|
|
|
|
|
func (m *Message) GetTypeMailaddr() (user, domain string, err error) { |
|
|
|
if err = m.GetType(M_MAILADDR); err != nil { |
|
|
|
func (m *message) GetTypeMailaddr() (user, domain string, err error) { |
|
|
|
if err = m.GetType(mMAILADDR); err != nil { |
|
|
|
return |
|
|
|
} |
|
|
|
return m.GetMailaddr() |
|
|
|
} |
|
|
|
|
|
|
|
func (m *Message) PutInt(v int) { |
|
|
|
func (m *message) PutInt(v int) { |
|
|
|
var b [4]byte |
|
|
|
binary.LittleEndian.PutUint32(b[:], uint32(v)) |
|
|
|
m.Data = append(m.Data, b[:]...) |
|
|
|
m.Len += 4 |
|
|
|
} |
|
|
|
|
|
|
|
func (m *Message) PutUint32(v uint32) { |
|
|
|
func (m *message) PutUint32(v uint32) { |
|
|
|
var b [4]byte |
|
|
|
binary.LittleEndian.PutUint32(b[:], v) |
|
|
|
m.Data = append(m.Data, b[:]...) |
|
|
|
m.Len += 4 |
|
|
|
} |
|
|
|
|
|
|
|
func (m *Message) PutString(s string) { |
|
|
|
func (m *message) PutString(s string) { |
|
|
|
m.Data = append(m.Data, append([]byte(s), 0)...) |
|
|
|
m.Len += uint16(len(s)) + 1 |
|
|
|
} |
|
|
|
|
|
|
|
func (m *Message) PutID(id uint64) { |
|
|
|
func (m *message) PutID(id uint64) { |
|
|
|
var b [8]byte |
|
|
|
binary.LittleEndian.PutUint64(b[:], id) |
|
|
|
m.Data = append(m.Data, b[:]...) |
|
|
|
m.Len += 8 |
|
|
|
} |
|
|
|
|
|
|
|
func (m *Message) PutType(t uint8) { |
|
|
|
func (m *message) PutType(t uint8) { |
|
|
|
m.Data = append(m.Data, t) |
|
|
|
m.Len += 1 |
|
|
|
} |
|
|
|
|
|
|
|
func (m *Message) PutTypeInt(v int) { |
|
|
|
m.PutType(M_INT) |
|
|
|
func (m *message) PutTypeInt(v int) { |
|
|
|
m.PutType(mINT) |
|
|
|
m.PutInt(v) |
|
|
|
} |
|
|
|
|
|
|
|
func (m *Message) PutTypeUint32(v uint32) { |
|
|
|
m.PutType(M_UINT32) |
|
|
|
func (m *message) PutTypeUint32(v uint32) { |
|
|
|
m.PutType(mUINT32) |
|
|
|
m.PutUint32(v) |
|
|
|
} |
|
|
|
|
|
|
|
func (m *Message) PutTypeString(s string) { |
|
|
|
m.PutType(M_STRING) |
|
|
|
func (m *message) PutTypeString(s string) { |
|
|
|
m.PutType(mSTRING) |
|
|
|
m.PutString(s) |
|
|
|
} |
|
|
|
|
|
|
|
func (m *Message) PutTypeID(id uint64) { |
|
|
|
m.PutType(M_ID) |
|
|
|
func (m *message) PutTypeID(id uint64) { |
|
|
|
m.PutType(mID) |
|
|
|
m.PutID(id) |
|
|
|
} |