cleanly separate version handling
This commit is contained in:
parent
bdb8c87a30
commit
5b8941ed37
103
packer/packer.go
103
packer/packer.go
|
@ -46,63 +46,68 @@ func splitHeader(header []byte, names []string) (map[string]string, error) {
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//ReadMessage -
|
// ReadMessage checks the protocol and switches accordingly
|
||||||
func ReadMessage(b []byte) (*Packer, error) {
|
func ReadMessage(b []byte) (*Packer, error) {
|
||||||
// Detect protocol in use
|
// Detect protocol in use
|
||||||
if b[0] == packerV1 {
|
if b[0] == packerV1 {
|
||||||
// Separate the header and body using the header length in the second byte.
|
return ReadV1Message(b)
|
||||||
p := NewPacker(nil)
|
|
||||||
header := b[2 : b[1]+2]
|
|
||||||
data := b[b[1]+2:]
|
|
||||||
|
|
||||||
// Handle the different parts of the header.
|
|
||||||
parts, err := splitHeader(header, []string{"address family", "address", "port", "data length", "service"})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if familyText := parts["address family"]; familyText == addressFamilyText[FamilyIPv4] {
|
|
||||||
p.Header.family = FamilyIPv4
|
|
||||||
} else if familyText == addressFamilyText[FamilyIPv6] {
|
|
||||||
p.Header.family = FamilyIPv6
|
|
||||||
} else {
|
|
||||||
return nil, fmt.Errorf("Address family %q not supported", familyText)
|
|
||||||
}
|
|
||||||
|
|
||||||
p.Header.address = net.ParseIP(parts["address"])
|
|
||||||
if p.Header.address == nil {
|
|
||||||
return nil, fmt.Errorf("Invalid network address %q", parts["address"])
|
|
||||||
} else if p.Header.family == FamilyIPv4 && p.Header.address.To4() == nil {
|
|
||||||
return nil, fmt.Errorf("Address %q is not in address family %s", parts["address"], p.Header.Family())
|
|
||||||
}
|
|
||||||
|
|
||||||
//handle port
|
|
||||||
if port, err := strconv.Atoi(parts["port"]); err != nil {
|
|
||||||
return nil, fmt.Errorf("Error converting port %q: %v", parts["port"], err)
|
|
||||||
} else if port <= 0 || port > 65535 {
|
|
||||||
return nil, fmt.Errorf("Port %d out of range", port)
|
|
||||||
} else {
|
|
||||||
p.Header.port = port
|
|
||||||
}
|
|
||||||
|
|
||||||
//handle data length
|
|
||||||
if dataLen, err := strconv.Atoi(parts["data length"]); err != nil {
|
|
||||||
return nil, fmt.Errorf("Error converting data length %q: %v", parts["data length"], err)
|
|
||||||
} else if dataLen != len(data) {
|
|
||||||
return nil, fmt.Errorf("Data length %d doesn't match received length %d", dataLen, len(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
//handle Service
|
|
||||||
p.Header.service = parts["service"]
|
|
||||||
|
|
||||||
//handle payload
|
|
||||||
p.Data.AppendBytes(data)
|
|
||||||
return p, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("Version %d not supported", 255-b[0])
|
return nil, fmt.Errorf("Version %d not supported", 255-b[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadV1Message parses a v1-formatted message
|
||||||
|
func ReadV1Message(b []byte) (*Packer, error) {
|
||||||
|
// Separate the header and body using the header length in the second byte.
|
||||||
|
p := NewPacker(nil)
|
||||||
|
header := b[2 : b[1]+2]
|
||||||
|
data := b[b[1]+2:]
|
||||||
|
|
||||||
|
// Handle the different parts of the header.
|
||||||
|
parts, err := splitHeader(header, []string{"address family", "address", "port", "data length", "service"})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if familyText := parts["address family"]; familyText == addressFamilyText[FamilyIPv4] {
|
||||||
|
p.Header.family = FamilyIPv4
|
||||||
|
} else if familyText == addressFamilyText[FamilyIPv6] {
|
||||||
|
p.Header.family = FamilyIPv6
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("Address family %q not supported", familyText)
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Header.address = net.ParseIP(parts["address"])
|
||||||
|
if p.Header.address == nil {
|
||||||
|
return nil, fmt.Errorf("Invalid network address %q", parts["address"])
|
||||||
|
} else if p.Header.family == FamilyIPv4 && p.Header.address.To4() == nil {
|
||||||
|
return nil, fmt.Errorf("Address %q is not in address family %s", parts["address"], p.Header.Family())
|
||||||
|
}
|
||||||
|
|
||||||
|
//handle port
|
||||||
|
if port, err := strconv.Atoi(parts["port"]); err != nil {
|
||||||
|
return nil, fmt.Errorf("Error converting port %q: %v", parts["port"], err)
|
||||||
|
} else if port <= 0 || port > 65535 {
|
||||||
|
return nil, fmt.Errorf("Port %d out of range", port)
|
||||||
|
} else {
|
||||||
|
p.Header.port = port
|
||||||
|
}
|
||||||
|
|
||||||
|
//handle data length
|
||||||
|
if dataLen, err := strconv.Atoi(parts["data length"]); err != nil {
|
||||||
|
return nil, fmt.Errorf("Error converting data length %q: %v", parts["data length"], err)
|
||||||
|
} else if dataLen != len(data) {
|
||||||
|
return nil, fmt.Errorf("Data length %d doesn't match received length %d", dataLen, len(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
//handle Service
|
||||||
|
p.Header.service = parts["service"]
|
||||||
|
|
||||||
|
//handle payload
|
||||||
|
p.Data.AppendBytes(data)
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
|
||||||
//PackV1 -- Outputs version 1 of packer
|
//PackV1 -- Outputs version 1 of packer
|
||||||
func (p *Packer) PackV1() bytes.Buffer {
|
func (p *Packer) PackV1() bytes.Buffer {
|
||||||
header := strings.Join([]string{
|
header := strings.Join([]string{
|
||||||
|
|
Loading…
Reference in New Issue