bep40.go | 25 +++++++++++++++++-------- bep40_test.go | 18 +++++++++++------- client.go | 2 +- diff --git a/bep40.go b/bep40.go index b92ef9d943bad4ac4e6b1fb6ab61e149c11bae04..e7debc748561e3f93c7b40a98c0cfdfa4ec5dcd9 100644 --- a/bep40.go +++ b/bep40.go @@ -3,6 +3,7 @@ import ( "bytes" "encoding/binary" + "errors" "fmt" "hash/crc32" @@ -53,30 +54,38 @@ } panic(fmt.Sprintf("%s %s", a, b)) } -func bep40PriorityBytes(a, b ipPort) []byte { +func bep40PriorityBytes(a, b ipPort) ([]byte, error) { if a.IP.Equal(b.IP) { var ret [4]byte binary.BigEndian.PutUint16(ret[0:2], a.Port) binary.BigEndian.PutUint16(ret[2:4], b.Port) - return ret[:] + return ret[:], nil } if a4, b4 := a.IP.To4(), b.IP.To4(); a4 != nil && b4 != nil { m := ipv4Mask(a.IP, b.IP) - return append(a4.Mask(m), b4.Mask(m)...) + return append(a4.Mask(m), b4.Mask(m)...), nil } if a6, b6 := a.IP.To16(), b.IP.To16(); a6 != nil && b6 != nil { m := ipv6Mask(a.IP, b.IP) - return append(a6.Mask(m), b6.Mask(m)...) + return append(a6.Mask(m), b6.Mask(m)...), nil } - panic(fmt.Sprintf("%s %s", a.IP, b.IP)) + return nil, errors.New("incomparable IPs") } -func bep40Priority(a, b ipPort) peerPriority { - bs := bep40PriorityBytes(a, b) +func bep40Priority(a, b ipPort) (peerPriority, error) { + bs, err := bep40PriorityBytes(a, b) + if err != nil { + return 0, nil + } i := len(bs) / 2 _a, _b := bs[:i], bs[i:] if bytes.Compare(_a, _b) > 0 { bs = append(_b, _a...) } - return crc32.Checksum(bs, table) + return crc32.Checksum(bs, table), nil +} + +func bep40PriorityIgnoreError(a, b ipPort) peerPriority { + prio, _ := bep40Priority(a, b) + return prio } diff --git a/bep40_test.go b/bep40_test.go index 4c82a5adb21978b26f6551e255284a8629ca90f5..78102149c1789323e9a899a88833e7f92b55d26c 100644 --- a/bep40_test.go +++ b/bep40_test.go @@ -8,20 +8,24 @@ "github.com/stretchr/testify/assert" ) func TestBep40Priority(t *testing.T) { - assert.EqualValues(t, 0xec2d7224, bep40Priority( + assert.EqualValues(t, 0xec2d7224, bep40PriorityIgnoreError( ipPort{net.ParseIP("123.213.32.10"), 0}, ipPort{net.ParseIP("98.76.54.32"), 0}, )) - assert.EqualValues(t, 0xec2d7224, bep40Priority( + assert.EqualValues(t, 0xec2d7224, bep40PriorityIgnoreError( ipPort{net.ParseIP("98.76.54.32"), 0}, ipPort{net.ParseIP("123.213.32.10"), 0}, )) - assert.Equal(t, peerPriority(0x99568189), bep40Priority( + assert.Equal(t, peerPriority(0x99568189), bep40PriorityIgnoreError( ipPort{net.ParseIP("123.213.32.10"), 0}, ipPort{net.ParseIP("123.213.32.234"), 0}, )) - assert.EqualValues(t, "\x00\x00\x00\x00", bep40PriorityBytes( - ipPort{net.ParseIP("123.213.32.234"), 0}, - ipPort{net.ParseIP("123.213.32.234"), 0}, - )) + assert.EqualValues(t, "\x00\x00\x00\x00", func() []byte { + b, _ := bep40PriorityBytes( + ipPort{net.ParseIP("123.213.32.234"), 0}, + ipPort{net.ParseIP("123.213.32.234"), 0}, + ) + return b + }()) + } diff --git a/client.go b/client.go index 7ea276d8aecfd31c574280c0dd9f2f1b7632c3d7..a07e3daca977101a7ae52bdedb669b7052ad4908 100644 --- a/client.go +++ b/client.go @@ -945,7 +945,7 @@ infoHash: ih, peers: prioritizedPeers{ om: btree.New(2), getPrio: func(p Peer) peerPriority { - return bep40Priority(cl.publicAddr(p.IP), p.addr()) + return bep40PriorityIgnoreError(cl.publicAddr(p.IP), p.addr()) }, }, conns: make(map[*connection]struct{}, 2*cl.config.EstablishedConnsPerTorrent),