Support IPv6 blocklists
Existing packed blocklists need to be regenerated.
This commit is contained in:
parent
924b916b2a
commit
8d1995c4d4
15
client.go
15
client.go
|
@ -398,24 +398,11 @@ func (cl *Client) Close() {
|
|||
cl.event.Broadcast()
|
||||
}
|
||||
|
||||
var ipv6BlockRange = iplist.Range{Description: "non-IPv4 address"}
|
||||
|
||||
func (cl *Client) ipBlockRange(ip net.IP) (r iplist.Range, blocked bool) {
|
||||
if cl.ipBlockList == nil {
|
||||
return
|
||||
}
|
||||
ip4 := ip.To4()
|
||||
// If blocklists are enabled, then block non-IPv4 addresses, because
|
||||
// blocklists do not yet support IPv6.
|
||||
if ip4 == nil {
|
||||
if missinggo.CryHeard() {
|
||||
log.Printf("blocking non-IPv4 address: %s", ip)
|
||||
}
|
||||
r = ipv6BlockRange
|
||||
blocked = true
|
||||
return
|
||||
}
|
||||
return cl.ipBlockList.Lookup(ip4)
|
||||
return cl.ipBlockList.Lookup(ip)
|
||||
}
|
||||
|
||||
func (cl *Client) waitAccept() {
|
||||
|
|
|
@ -78,15 +78,13 @@ func lookupOk(r Range, ok bool) bool {
|
|||
|
||||
func TestBadIP(t *testing.T) {
|
||||
for _, iplist := range []Ranger{
|
||||
New(nil),
|
||||
// New(nil),
|
||||
NewFromPacked([]byte("\x00\x00\x00\x00\x00\x00\x00\x00")),
|
||||
} {
|
||||
assert.False(t, lookupOk(iplist.Lookup(net.IP(make([]byte, 4)))), "%v", iplist)
|
||||
assert.False(t, lookupOk(iplist.Lookup(net.IP(make([]byte, 16)))))
|
||||
r, ok := iplist.Lookup(nil)
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, r.Description, "bad IP")
|
||||
assert.True(t, lookupOk(iplist.Lookup(net.IP(make([]byte, 5)))))
|
||||
assert.Panics(t, func() { iplist.Lookup(nil) })
|
||||
assert.Panics(t, func() { iplist.Lookup(net.IP(make([]byte, 5))) })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,11 +99,12 @@ func testLookuperSimple(t *testing.T, iplist Ranger) {
|
|||
{"1.2.4.255", true, "a"},
|
||||
// Try to roll over to the next octet on the parse. Note the final
|
||||
// octet is overbounds. In the next case.
|
||||
{"1.2.7.256", true, "bad IP"},
|
||||
// {"1.2.7.256", true, "bad IP"},
|
||||
{"1.2.8.1", true, "b"},
|
||||
{"1.2.8.2", true, "eff"},
|
||||
} {
|
||||
ip := net.ParseIP(_case.IP)
|
||||
require.NotNil(t, ip, _case.IP)
|
||||
r, ok := iplist.Lookup(ip)
|
||||
assert.Equal(t, _case.Hit, ok, "%s", _case)
|
||||
if !_case.Hit {
|
||||
|
|
|
@ -2,6 +2,7 @@ package iplist
|
|||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
|
@ -18,7 +19,7 @@ import (
|
|||
|
||||
const (
|
||||
packedRangesOffset = 8
|
||||
packedRangeLen = 20
|
||||
packedRangeLen = 44
|
||||
)
|
||||
|
||||
func (ipl *IPList) WritePacked(w io.Writer) (err error) {
|
||||
|
@ -43,8 +44,8 @@ func (ipl *IPList) WritePacked(w io.Writer) (err error) {
|
|||
binary.LittleEndian.PutUint64(b[:], uint64(len(ipl.ranges)))
|
||||
write(b[:], 8)
|
||||
for _, r := range ipl.ranges {
|
||||
write(r.First.To4(), 4)
|
||||
write(r.Last.To4(), 4)
|
||||
write(r.First.To16(), 16)
|
||||
write(r.Last.To16(), 16)
|
||||
descOff, ok := descOffsets[r.Description]
|
||||
if !ok {
|
||||
descOff = nextOffset
|
||||
|
@ -64,7 +65,12 @@ func (ipl *IPList) WritePacked(w io.Writer) (err error) {
|
|||
}
|
||||
|
||||
func NewFromPacked(b []byte) PackedIPList {
|
||||
return PackedIPList(b)
|
||||
ret := PackedIPList(b)
|
||||
minLen := packedRangesOffset + ret.len()*packedRangeLen
|
||||
if len(b) < minLen {
|
||||
panic(fmt.Sprintf("packed len %d < %d", len(b), minLen))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
type PackedIPList []byte
|
||||
|
@ -81,14 +87,14 @@ func (pil PackedIPList) NumRanges() int {
|
|||
|
||||
func (pil PackedIPList) getFirst(i int) net.IP {
|
||||
off := packedRangesOffset + packedRangeLen*i
|
||||
return net.IP(pil[off : off+4])
|
||||
return net.IP(pil[off : off+16])
|
||||
}
|
||||
|
||||
func (pil PackedIPList) getRange(i int) (ret Range) {
|
||||
rOff := packedRangesOffset + packedRangeLen*i
|
||||
last := pil[rOff+4 : rOff+8]
|
||||
descOff := int(binary.LittleEndian.Uint64(pil[rOff+8:]))
|
||||
descLen := int(binary.LittleEndian.Uint32(pil[rOff+16:]))
|
||||
last := pil[rOff+16 : rOff+32]
|
||||
descOff := int(binary.LittleEndian.Uint64(pil[rOff+32:]))
|
||||
descLen := int(binary.LittleEndian.Uint32(pil[rOff+40:]))
|
||||
descOff += packedRangesOffset + packedRangeLen*pil.len()
|
||||
ret = Range{
|
||||
pil.getFirst(i),
|
||||
|
@ -99,19 +105,11 @@ func (pil PackedIPList) getRange(i int) (ret Range) {
|
|||
}
|
||||
|
||||
func (pil PackedIPList) Lookup(ip net.IP) (r Range, ok bool) {
|
||||
ip4 := ip.To4()
|
||||
if ip4 == nil {
|
||||
// If the IP list was built successfully, then it only contained IPv4
|
||||
// ranges. Therefore no IPv6 ranges are blocked.
|
||||
if ip.To16() == nil {
|
||||
r = Range{
|
||||
Description: "bad IP",
|
||||
}
|
||||
ok = true
|
||||
}
|
||||
return
|
||||
ip16 := ip.To16()
|
||||
if ip16 == nil {
|
||||
panic(ip)
|
||||
}
|
||||
return lookup(pil.getFirst, pil.getRange, pil.len(), ip4)
|
||||
return lookup(pil.getFirst, pil.getRange, pil.len(), ip16)
|
||||
}
|
||||
|
||||
type closerFunc func() error
|
||||
|
|
|
@ -25,11 +25,11 @@ func TestWritePacked(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
require.Equal(t,
|
||||
"\x05\x00\x00\x00\x00\x00\x00\x00"+
|
||||
"\x01\x02\x04\x00\x01\x02\x04\xff"+"\x00\x00\x00\x00\x00\x00\x00\x00"+"\x01\x00\x00\x00"+
|
||||
"\x01\x02\x08\x00\x01\x02\x08\xff"+"\x01\x00\x00\x00\x00\x00\x00\x00"+"\x01\x00\x00\x00"+
|
||||
"\x01\x02\x08\x02\x01\x02\x08\x02"+"\x02\x00\x00\x00\x00\x00\x00\x00"+"\x03\x00\x00\x00"+
|
||||
"\x56\x3b\x5f\xc3\x56\x3b\x5f\xc3"+"\x05\x00\x00\x00\x00\x00\x00\x00"+"\x15\x00\x00\x00"+
|
||||
"\x7f\x00\x00\x00\x7f\x00\x00\x01"+"\x02\x00\x00\x00\x00\x00\x00\x00"+"\x03\x00\x00\x00"+
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x01\x02\x04\x00"+"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x01\x02\x04\xff"+"\x00\x00\x00\x00\x00\x00\x00\x00"+"\x01\x00\x00\x00"+
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x01\x02\x08\x00"+"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x01\x02\x08\xff"+"\x01\x00\x00\x00\x00\x00\x00\x00"+"\x01\x00\x00\x00"+
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x01\x02\x08\x02"+"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x01\x02\x08\x02"+"\x02\x00\x00\x00\x00\x00\x00\x00"+"\x03\x00\x00\x00"+
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x56\x3b\x5f\xc3"+"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x56\x3b\x5f\xc3"+"\x05\x00\x00\x00\x00\x00\x00\x00"+"\x15\x00\x00\x00"+
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x7f\x00\x00\x00"+"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x7f\x00\x00\x01"+"\x02\x00\x00\x00\x00\x00\x00\x00"+"\x03\x00\x00\x00"+
|
||||
"abeffsomething:more detail",
|
||||
buf.String())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue