]> Sergey Matveev's repositories - btrtrc.git/commitdiff
iplist: Fix ranges that contain extra colons, and minimize memory use for IP
authorMatt Joiner <anacrolix@gmail.com>
Sun, 8 Mar 2015 06:43:44 +0000 (17:43 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Sun, 8 Mar 2015 06:43:44 +0000 (17:43 +1100)
iplist/iplist.go
iplist/iplist_test.go

index d04b090589d00ebca1a2f89a4367a3cc9d73c02c..5585909bed393b78e7603a5b86b7d3f1bad36be6 100644 (file)
@@ -77,6 +77,13 @@ func (me *IPList) lookup(ip net.IP) (r *Range) {
        return
 }
 
+func minifyIP(ip *net.IP) {
+       v4 := ip.To4()
+       if v4 != nil {
+               *ip = append(make([]byte, 0, 4), v4...)
+       }
+}
+
 // Parse a line of the PeerGuardian Text Lists (P2P) Format. Returns !ok but
 // no error if a line doesn't contain a range but isn't erroneous, such as
 // comment and blank lines.
@@ -85,7 +92,9 @@ func ParseBlocklistP2PLine(l []byte) (r Range, ok bool, err error) {
        if len(l) == 0 || bytes.HasPrefix(l, []byte("#")) {
                return
        }
-       colon := bytes.IndexByte(l, ':')
+       // TODO: Something tells me this will end badly when IPv6 blocklists are
+       // added.
+       colon := bytes.LastIndexAny(l, ":")
        if colon == -1 {
                err = errors.New("missing colon")
                return
@@ -98,8 +107,11 @@ func ParseBlocklistP2PLine(l []byte) (r Range, ok bool, err error) {
        hyphen += colon + 1
        r.Description = string(l[:colon])
        r.First = net.ParseIP(string(l[colon+1 : hyphen]))
+       minifyIP(&r.First)
        r.Last = net.ParseIP(string(l[hyphen+1:]))
-       if r.First == nil || r.Last == nil {
+       minifyIP(&r.Last)
+       if r.First == nil || r.Last == nil || len(r.First) != len(r.Last) {
+               err = errors.New("bad IP range")
                return
        }
        ok = true
index 08f5b80fdeb61a608db7de214ab4c5be791b418f..6b8ff1f08c883c509805c1fd1811b31f818f6c41 100644 (file)
@@ -2,23 +2,43 @@ package iplist
 
 import (
        "bufio"
+       "fmt"
        "net"
        "strings"
        "testing"
+
+       "github.com/bradfitz/iter"
+
+       "bitbucket.org/anacrolix/go.torrent/util"
 )
 
 var sample = `
 # List distributed by iblocklist.com
 
 a:1.2.4.0-1.2.4.255
-b:1.2.8.0-1.2.8.255`
+b:1.2.8.0-1.2.8.255
+something:more detail:86.59.95.195-86.59.95.195`
+
+func TestIPv4RangeLen(t *testing.T) {
+       ranges, _ := sampleRanges(t)
+       for i := range iter.N(3) {
+               if len(ranges[i].First) != 4 {
+                       t.FailNow()
+               }
+               if len(ranges[i].Last) != 4 {
+                       t.FailNow()
+               }
+       }
+}
 
 func sampleRanges(tb testing.TB) (ranges []Range, err error) {
        scanner := bufio.NewScanner(strings.NewReader(sample))
        for scanner.Scan() {
-               r, ok, _ := ParseBlocklistP2PLine(scanner.Bytes())
+               r, ok, err := ParseBlocklistP2PLine(scanner.Bytes())
+               if err != nil {
+                       tb.Fatal(err)
+               }
                if ok {
-                       // tb.Log(r)
                        ranges = append(ranges, r)
                }
        }
@@ -32,13 +52,34 @@ func BenchmarkParseP2pBlocklist(b *testing.B) {
        }
 }
 
+func connRemoteAddrIP(network, laddr string, dialHost string) net.IP {
+       l, err := net.Listen(network, laddr)
+       if err != nil {
+               panic(err)
+       }
+       go func() {
+               c, err := net.Dial(network, net.JoinHostPort(dialHost, fmt.Sprintf("%d", util.AddrPort(l.Addr()))))
+               if err != nil {
+                       panic(err)
+               }
+               defer c.Close()
+       }()
+       c, err := l.Accept()
+       if err != nil {
+               panic(err)
+       }
+       defer c.Close()
+       ret := util.AddrIP(c.RemoteAddr())
+       return ret
+}
+
 func TestSimple(t *testing.T) {
        ranges, err := sampleRanges(t)
        if err != nil {
                t.Fatal(err)
        }
-       if len(ranges) != 2 {
-               t.Fatalf("expected 2 ranges but got %d", len(ranges))
+       if len(ranges) != 3 {
+               t.Fatalf("expected 3 ranges but got %d", len(ranges))
        }
        iplist := New(ranges)
        for _, _case := range []struct {