powerdns-remote-http-example/addr-map.go
2024-06-04 03:20:21 +03:00

44 lines
968 B
Go

package main
import (
"encoding/binary"
"log"
"net"
"github.com/cespare/xxhash/v2"
)
// TODO: write more convenient version
func addrMap(srcIp net.IP, dstCidr *net.IPNet) net.IP {
addrlen := len(srcIp)
if addrlen != len(dstCidr.IP) {
log.Fatalf("addrMap(): src/dst size mismatch: %v vs %v", len(srcIp), len(dstCidr.IP))
}
var addr net.IP = make([]byte, addrlen)
hsum := xxhash.Sum64(srcIp)
bsum := binary.NativeEndian.AppendUint64([]byte{}, hsum)
blen := len(bsum)
if addrlen > blen {
// extend bsum
tmp := append(make([]byte, addrlen-blen), bsum...)
bsum = tmp
}
if addrlen < blen {
// trim bsum
bsum = bsum[:addrlen]
}
// apply inverted mask to bsum and sum with addr
for i := range addrlen / 4 {
a := binary.NativeEndian.Uint32(dstCidr.IP[i*4:])
b := binary.NativeEndian.Uint32(bsum[i*4:])
m := binary.NativeEndian.Uint32(dstCidr.Mask[i*4:])
a += (b & ^m)
binary.NativeEndian.PutUint32(addr[i*4:], a)
}
return addr
}