Maintain host bits for inet types

non-blocking
Cameron Daniel 2021-06-30 14:22:26 +02:00 committed by Jack Christensen
parent 2ca304d461
commit 3eceab0f38
3 changed files with 54 additions and 20 deletions

15
inet.go
View File

@ -132,18 +132,22 @@ func (dst *Inet) DecodeText(ci *ConnInfo, src []byte) error {
var err error var err error
if ip := net.ParseIP(string(src)); ip != nil { if ip := net.ParseIP(string(src)); ip != nil {
ipv4 := ip.To4() if ipv4 := ip.To4(); ipv4 != nil {
if ipv4 != nil {
ip = ipv4 ip = ipv4
} }
bitCount := len(ip) * 8 bitCount := len(ip) * 8
mask := net.CIDRMask(bitCount, bitCount) mask := net.CIDRMask(bitCount, bitCount)
ipnet = &net.IPNet{Mask: mask, IP: ip} ipnet = &net.IPNet{Mask: mask, IP: ip}
} else { } else {
_, ipnet, err = net.ParseCIDR(string(src)) ip, ipnet, err = net.ParseCIDR(string(src))
if err != nil { if err != nil {
return err return err
} }
if ipv4 := ip.To4(); ipv4 != nil {
ip = ipv4
}
ones, _ := ipnet.Mask.Size()
*ipnet = net.IPNet{IP: ip, Mask: net.CIDRMask(ones, len(ip)*8)}
} }
*dst = Inet{IPNet: ipnet, Status: Present} *dst = Inet{IPNet: ipnet, Status: Present}
@ -168,7 +172,10 @@ func (dst *Inet) DecodeBinary(ci *ConnInfo, src []byte) error {
var ipnet net.IPNet var ipnet net.IPNet
ipnet.IP = make(net.IP, int(addressLength)) ipnet.IP = make(net.IP, int(addressLength))
copy(ipnet.IP, src[4:]) copy(ipnet.IP, src[4:])
ipnet.Mask = net.CIDRMask(int(bits), int(addressLength)*8) if ipv4 := ipnet.IP.To4(); ipv4 != nil {
ipnet.IP = ipv4
}
ipnet.Mask = net.CIDRMask(int(bits), len(ipnet.IP)*8)
*dst = Inet{IPNet: &ipnet, Status: Present} *dst = Inet{IPNet: &ipnet, Status: Present}

View File

@ -11,22 +11,35 @@ import (
) )
func TestInetTranscode(t *testing.T) { func TestInetTranscode(t *testing.T) {
for _, pgTypeName := range []string{"inet", "cidr"} { testutil.TestSuccessfulTranscode(t, "inet", []interface{}{
testutil.TestSuccessfulTranscode(t, pgTypeName, []interface{}{ &pgtype.Inet{IPNet: mustParseInet(t, "0.0.0.0/32"), Status: pgtype.Present},
&pgtype.Inet{IPNet: mustParseCIDR(t, "0.0.0.0/32"), Status: pgtype.Present}, &pgtype.Inet{IPNet: mustParseInet(t, "127.0.0.1/8"), Status: pgtype.Present},
&pgtype.Inet{IPNet: mustParseCIDR(t, "127.0.0.1/32"), Status: pgtype.Present}, &pgtype.Inet{IPNet: mustParseInet(t, "12.34.56.65/32"), Status: pgtype.Present},
&pgtype.Inet{IPNet: mustParseCIDR(t, "12.34.56.0/32"), Status: pgtype.Present}, &pgtype.Inet{IPNet: mustParseInet(t, "192.168.1.16/24"), Status: pgtype.Present},
&pgtype.Inet{IPNet: mustParseCIDR(t, "192.168.1.0/24"), Status: pgtype.Present}, &pgtype.Inet{IPNet: mustParseInet(t, "255.0.0.0/8"), Status: pgtype.Present},
&pgtype.Inet{IPNet: mustParseCIDR(t, "192.168.1.50/24"), Status: pgtype.Present}, &pgtype.Inet{IPNet: mustParseInet(t, "255.255.255.255/32"), Status: pgtype.Present},
&pgtype.Inet{IPNet: mustParseCIDR(t, "255.0.0.0/8"), Status: pgtype.Present}, &pgtype.Inet{IPNet: mustParseInet(t, "::1/64"), Status: pgtype.Present},
&pgtype.Inet{IPNet: mustParseCIDR(t, "255.255.255.255/32"), Status: pgtype.Present}, &pgtype.Inet{IPNet: mustParseInet(t, "::/0"), Status: pgtype.Present},
&pgtype.Inet{IPNet: mustParseCIDR(t, "::/128"), Status: pgtype.Present}, &pgtype.Inet{IPNet: mustParseInet(t, "::1/128"), Status: pgtype.Present},
&pgtype.Inet{IPNet: mustParseCIDR(t, "::/0"), Status: pgtype.Present}, &pgtype.Inet{IPNet: mustParseInet(t, "2607:f8b0:4009:80b::200e/64"), Status: pgtype.Present},
&pgtype.Inet{IPNet: mustParseCIDR(t, "::1/128"), Status: pgtype.Present}, &pgtype.Inet{Status: pgtype.Null},
&pgtype.Inet{IPNet: mustParseCIDR(t, "2607:f8b0:4009:80b::200e/128"), Status: pgtype.Present}, })
&pgtype.Inet{Status: pgtype.Null}, }
})
} func TestCidrTranscode(t *testing.T) {
testutil.TestSuccessfulTranscode(t, "cidr", []interface{}{
&pgtype.Inet{IPNet: mustParseCIDR(t, "0.0.0.0/32"), Status: pgtype.Present},
&pgtype.Inet{IPNet: mustParseCIDR(t, "127.0.0.1/32"), Status: pgtype.Present},
&pgtype.Inet{IPNet: mustParseCIDR(t, "12.34.56.0/32"), Status: pgtype.Present},
&pgtype.Inet{IPNet: mustParseCIDR(t, "192.168.1.0/24"), Status: pgtype.Present},
&pgtype.Inet{IPNet: mustParseCIDR(t, "255.0.0.0/8"), Status: pgtype.Present},
&pgtype.Inet{IPNet: mustParseCIDR(t, "255.255.255.255/32"), Status: pgtype.Present},
&pgtype.Inet{IPNet: mustParseCIDR(t, "::/128"), Status: pgtype.Present},
&pgtype.Inet{IPNet: mustParseCIDR(t, "::/0"), Status: pgtype.Present},
&pgtype.Inet{IPNet: mustParseCIDR(t, "::1/128"), Status: pgtype.Present},
&pgtype.Inet{IPNet: mustParseCIDR(t, "2607:f8b0:4009:80b::200e/128"), Status: pgtype.Present},
&pgtype.Inet{Status: pgtype.Null},
})
} }
func TestInetSet(t *testing.T) { func TestInetSet(t *testing.T) {

View File

@ -35,6 +35,20 @@ func mustParseCIDR(t testing.TB, s string) *net.IPNet {
return ipnet return ipnet
} }
func mustParseInet(t testing.TB, s string) *net.IPNet {
ip, ipnet, err := net.ParseCIDR(s)
if err != nil {
t.Fatal(err)
}
if ipv4 := ip.To4(); ipv4 != nil {
ip = ipv4
}
ipnet.IP = ip
return ipnet
}
func mustParseMacaddr(t testing.TB, s string) net.HardwareAddr { func mustParseMacaddr(t testing.TB, s string) net.HardwareAddr {
addr, err := net.ParseMAC(s) addr, err := net.ParseMAC(s)
if err != nil { if err != nil {