1
0
Fork 0
telegraf/plugins/inputs/powerdns_recursor/protocol_commons.go

90 lines
2.1 KiB
Go
Raw Normal View History

package powerdns_recursor
import (
"errors"
"fmt"
"net"
"strconv"
"strings"
"github.com/influxdata/telegraf/internal"
)
func parseResponse(metrics string) map[string]interface{} {
values := make(map[string]interface{})
s := strings.Split(metrics, "\n")
if len(s) < 1 {
return values
}
for _, metric := range s[:len(s)-1] {
m := strings.Split(metric, "\t")
if len(m) < 2 {
continue
}
i, err := strconv.ParseInt(m[1], 10, 64)
if err != nil {
continue
}
values[m[0]] = i
}
return values
}
// This below is generally unsafe but necessary in this case
// since the powerdns protocol encoding is host dependent.
// The C implementation uses size_t as the size type for the
// command length. The size and endianness of size_t change
// depending on the platform the program is being run on.
// Using the target architecture endianness and the known
// integer size, we can "recreate" the corresponding C
// behavior in an effort to maintain compatibility. Of course
// in cases where one program is compiled for i386 and the
// other for amd64 (and similar), this method will fail.
const uintSizeInBytes = strconv.IntSize / 8
func writeNativeUIntToConn(conn net.Conn, value uint) error {
intData := make([]byte, uintSizeInBytes)
switch uintSizeInBytes {
case 4:
internal.HostEndianness.PutUint32(intData, uint32(value))
case 8:
internal.HostEndianness.PutUint64(intData, uint64(value))
default:
return errors.New("unsupported system configuration")
}
_, err := conn.Write(intData)
return err
}
func readNativeUIntFromConn(conn net.Conn) (uint, error) {
intData := make([]byte, uintSizeInBytes)
n, err := conn.Read(intData)
if err != nil {
return 0, err
}
if n != uintSizeInBytes {
return 0, fmt.Errorf("did not read enough data for native uint: read '%v' bytes, expected '%v'", n, uintSizeInBytes)
}
switch uintSizeInBytes {
case 4:
return uint(internal.HostEndianness.Uint32(intData)), nil
case 8:
return uint(internal.HostEndianness.Uint64(intData)), nil
default:
return 0, errors.New("unsupported system configuration")
}
}