Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dht_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func TestSetNilBigInt(t *testing.T) {
}

func TestMarshalCompactNodeInfo(t *testing.T) {
cni := krpc.CompactIPv4NodeInfo{krpc.NodeInfo{
cni := krpc.CompactNodeInfo{krpc.NodeInfo{
ID: [20]byte{'a', 'b', 'c'},
}}
addr, err := net.ResolveUDPAddr("udp4", "1.2.3.4:5")
Expand Down
36 changes: 0 additions & 36 deletions krpc/CompactIPv4NodeAddrs.go

This file was deleted.

5 changes: 2 additions & 3 deletions krpc/CompactIPv6NodeAddrs.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ type CompactIPv6NodeAddrs []NodeAddr
func (CompactIPv6NodeAddrs) ElemSize() int { return 18 }

func (me CompactIPv6NodeAddrs) MarshalBinary() ([]byte, error) {
return marshalBinarySlice(slices.Map(func(na NodeAddr) NodeAddr {
na.IP = na.IP.To16()
return na
return marshalBinarySlice(slices.Map(func(addr NodeAddr) NodeAddr {
return addr.Compacted()
}, me).(CompactIPv6NodeAddrs))
}

Expand Down
40 changes: 40 additions & 0 deletions krpc/CompactNodeAddrs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package krpc

import "github.com/anacrolix/missinggo/slices"

const (
ipv4AddrSize = 6
i2pAddrSize = 34
)

var nodeAddrNumBytes = ipv4AddrSize

type CompactNodeAddrs []NodeAddr

func (CompactNodeAddrs) ElemSize() int { return nodeAddrNumBytes }

func (me CompactNodeAddrs) MarshalBinary() ([]byte, error) {
return marshalBinarySlice(slices.Map(func(addr NodeAddr) NodeAddr {
return addr.Compacted()
}, me).(CompactNodeAddrs))
}

func (me CompactNodeAddrs) MarshalBencode() ([]byte, error) {
return bencodeBytesResult(me.MarshalBinary())
}

func (me *CompactNodeAddrs) UnmarshalBinary(b []byte) error {
return unmarshalBinarySlice(me, b)
}

func (me *CompactNodeAddrs) UnmarshalBencode(b []byte) error {
return unmarshalBencodedBinary(me, b)
}

func (me CompactNodeAddrs) NodeAddrs() []NodeAddr {
return me
}

func (me CompactNodeAddrs) Index(x NodeAddr) int {
return addrIndex(me, x)
}
18 changes: 9 additions & 9 deletions krpc/CompactIPv4NodeInfo.go → krpc/CompactNodeInfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ package krpc
import "github.com/anacrolix/missinggo/slices"

type (
CompactIPv4NodeInfo []NodeInfo
CompactNodeInfo []NodeInfo
)

func (CompactIPv4NodeInfo) ElemSize() int {
return 26
func (CompactNodeInfo) ElemSize() int {
return 20 + nodeAddrNumBytes
}

// func (me *CompactIPv4NodeInfo) Scrub() {
Expand All @@ -17,21 +17,21 @@ func (CompactIPv4NodeInfo) ElemSize() int {
// })
// }

func (me CompactIPv4NodeInfo) MarshalBinary() ([]byte, error) {
func (me CompactNodeInfo) MarshalBinary() ([]byte, error) {
return marshalBinarySlice(slices.Map(func(ni NodeInfo) NodeInfo {
ni.Addr.IP = ni.Addr.IP.To4()
ni.Addr = ni.Addr.Compacted()
return ni
}, me).(CompactIPv4NodeInfo))
}, me).(CompactNodeInfo))
}

func (me CompactIPv4NodeInfo) MarshalBencode() ([]byte, error) {
func (me CompactNodeInfo) MarshalBencode() ([]byte, error) {
return bencodeBytesResult(me.MarshalBinary())
}

func (me *CompactIPv4NodeInfo) UnmarshalBinary(b []byte) error {
func (me *CompactNodeInfo) UnmarshalBinary(b []byte) error {
return unmarshalBinarySlice(me, b)
}

func (me *CompactIPv4NodeInfo) UnmarshalBencode(b []byte) error {
func (me *CompactNodeInfo) UnmarshalBencode(b []byte) error {
return unmarshalBencodedBinary(me, b)
}
143 changes: 121 additions & 22 deletions krpc/compact_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,47 +9,74 @@ import (
)

func TestUnmarshalSlice(t *testing.T) {
var data CompactIPv4NodeInfo
var data CompactNodeInfo
err := data.UnmarshalBencode([]byte("52:" +
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06" +
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x03\x04\x05\x06\x07"))
require.NoError(t, err)
require.Len(t, data, 2)
assert.Equal(t, "1.2.3.4", data[0].Addr.IP.String())
assert.Equal(t, "2.3.4.5", data[1].Addr.IP.String())
assert.Equal(t, "1.2.3.4", data[0].Addr.Host())
assert.Equal(t, "2.3.4.5", data[1].Addr.Host())
}

func TestUnmarshalSliceI2P(t *testing.T) {
SetNetworkType(I2PNet)
defer SetNetworkType(IPNet)

nodeId := "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
port := "\x01\x01"

dest1 := makeTestAddr32(dest32_3)
dest2 := makeTestAddr32(dest32_1)

var data CompactNodeInfo
err := data.UnmarshalBencode([]byte("108:" +
nodeId + string(dest1) + port +
nodeId + string(dest2) + port))

require.NoError(t, err)
require.Len(t, data, 2)
assert.Equal(t, dest32_3+suffixb32, data[0].Addr.Host())
assert.Equal(t, dest32_1+suffixb32, data[1].Addr.Host())
}

var testNodeIPAddr1 = NewNodeIPAddr(IPv4(172, 16, 1, 1), 11)
var testNodeIPAddr2 = NewNodeIPAddr(IPv4(192, 168, 0, 3), 11)
var testNodeIPAddr3 = NewNodeIPAddr(IPv4(127, 0, 0, 1), 11)

var nodeAddrIndexTests4 = []struct {
v CompactIPv4NodeAddrs
v CompactNodeAddrs
a NodeAddr
out int
}{
{[]NodeAddr{{IPv4(172, 16, 1, 1), 11}, {IPv4(192, 168, 0, 3), 11}}, NodeAddr{IPv4(172, 16, 1, 1), 11}, 0},
{[]NodeAddr{{IPv4(172, 16, 1, 1), 11}, {IPv4(192, 168, 0, 3), 11}}, NodeAddr{IPv4(192, 168, 0, 3), 11}, 1},
{[]NodeAddr{{IPv4(172, 16, 1, 1), 11}, {IPv4(192, 168, 0, 3), 11}}, NodeAddr{IPv4(127, 0, 0, 1), 11}, -1},
{[]NodeAddr{}, NodeAddr{IPv4(127, 0, 0, 1), 11}, -1},
{[]NodeAddr{}, NodeAddr{}, -1},
{[]NodeAddr{testNodeIPAddr1, testNodeIPAddr2}, testNodeIPAddr1, 0},
{[]NodeAddr{testNodeIPAddr1, testNodeIPAddr2}, testNodeIPAddr2, 1},
{[]NodeAddr{testNodeIPAddr1, testNodeIPAddr2}, testNodeIPAddr3, -1},
{[]NodeAddr{}, testNodeIPAddr3, -1},
}

func TestNodeAddrIndex4(t *testing.T) {
for _, tc := range nodeAddrIndexTests4 {
out := tc.v.Index(tc.a)
if out != tc.out {
t.Errorf("CompactIPv4NodeAddrs(%v).Index(%v) = %v, want %v", tc.v, tc.a, out, tc.out)
t.Errorf("IPv4:CompactNodeAddrs(%v).Index(%v) = %v, want %v", tc.v, tc.a, out, tc.out)
}
}
}

var testNodeIPv6Addr1 = NewNodeIPAddr(ParseIP("2001::1"), 11)
var testNodeIPv6Addr2 = NewNodeIPAddr(ParseIP("4004::1"), 11)
var testNodeIPv6Addr3 = NewNodeIPAddr(ParseIP("::1"), 11)

var nodeAddrIndexTests6 = []struct {
v CompactIPv6NodeAddrs
a NodeAddr
out int
}{
{[]NodeAddr{{ParseIP("2001::1"), 11}, {ParseIP("4004::1"), 11}}, NodeAddr{ParseIP("2001::1"), 11}, 0},
{[]NodeAddr{{ParseIP("2001::1"), 11}, {ParseIP("4004::1"), 11}}, NodeAddr{ParseIP("4004::1"), 11}, 1},
{[]NodeAddr{{ParseIP("2001::1"), 11}, {ParseIP("4004::1"), 11}}, NodeAddr{ParseIP("::1"), 11}, -1},
{[]NodeAddr{}, NodeAddr{ParseIP("::1"), 11}, -1},
{[]NodeAddr{}, NodeAddr{}, -1},
{[]NodeAddr{testNodeIPv6Addr1, testNodeIPv6Addr2}, testNodeIPv6Addr1, 0},
{[]NodeAddr{testNodeIPv6Addr1, testNodeIPv6Addr2}, testNodeIPv6Addr2, 1},
{[]NodeAddr{testNodeIPv6Addr1, testNodeIPv6Addr2}, testNodeIPv6Addr3, -1},
{[]NodeAddr{}, testNodeIPv6Addr3, -1},
}

func TestNodeAddrIndex6(t *testing.T) {
Expand All @@ -61,22 +88,94 @@ func TestNodeAddrIndex6(t *testing.T) {
}
}

var testNodeI2PAddr1 = NewNodeI2PAddr(makeTestAddr32(dest32_1), 2)
var testNodeI2PAddr2 = NewNodeI2PAddr(makeTestAddr64(dest64_2), 2)
var testNodeI2PAddr3 = NewNodeI2PAddr(makeTestAddr32(dest32_3), 2)
var testNodeI2PAddr4 = NewNodeI2PAddr(makeTestAddr64(dest64_3), 2)

var nodeAddrIndexTestsI2P = []struct {
v CompactNodeAddrs
a NodeAddr
out int
}{
{[]NodeAddr{testNodeI2PAddr1, testNodeI2PAddr2}, testNodeI2PAddr1, 0},
{[]NodeAddr{testNodeI2PAddr2, testNodeI2PAddr3}, testNodeI2PAddr3, 1},
{[]NodeAddr{testNodeI2PAddr1, testNodeI2PAddr2}, testNodeI2PAddr3, -1},
}

func TestNodeAddrIndexI2P(t *testing.T) {
for _, tc := range nodeAddrIndexTestsI2P {
out := tc.v.Index(tc.a)
if out != tc.out {
t.Errorf("I2P:CompactNodeAddrs(%v).Index(%v) = %v, want %v", tc.v, tc.a, out, tc.out)
}
}
}

func i2pNodeAddrBytes(addr NodeAddr) []byte {
var addrBytes []byte = addr.I2PAddress
portBytes := []byte{0, 2}

return append(addrBytes, portBytes...)
}

func TestMarshalI2PCompactNodeAddrs(t *testing.T) {
SetNetworkType(I2PNet)
defer SetNetworkType(IPNet)

testNodeI2PAddr3Bytes := i2pNodeAddrBytes(testNodeI2PAddr3)

testNodeI2PAddr2Compacted := testNodeI2PAddr2.Compacted()
testNodeI2PAddr2CompactedBytes := i2pNodeAddrBytes(testNodeI2PAddr2Compacted)

var marshalI2PSliceTests = []struct {
in CompactNodeAddrs
out []byte
panics bool
}{
{[]NodeAddr{testNodeI2PAddr1}, i2pNodeAddrBytes(testNodeI2PAddr1), false},
{[]NodeAddr{testNodeI2PAddr3}, testNodeI2PAddr3Bytes, false},
{[]NodeAddr{testNodeI2PAddr2}, testNodeI2PAddr2CompactedBytes, false},
{[]NodeAddr{testNodeI2PAddr3, testNodeI2PAddr2},
append(testNodeI2PAddr3Bytes, testNodeI2PAddr2CompactedBytes...),
false},
{[]NodeAddr{NewNodeI2PAddr(nil, 0)}, nil, true},
}

for _, tc := range marshalI2PSliceTests {
runFunc := assert.NotPanics
if tc.panics {
runFunc = assert.Panics
}
runFunc(t, func() {
out, err := tc.in.MarshalBinary()
require.NoError(t, err)
assert.Equal(t, tc.out, out, "for input %v, %v", tc.in)
})
}
}

var testMarshalIPv4Addr1 = NewNodeIPAddr(net.IP{172, 16, 1, 1}, 3)
var testMarshalIPv4Addr2 = NewNodeIPAddr(net.IPv4(172, 16, 1, 1), 4)
var testMarshalIPv4Addr3 = NewNodeIPAddr(net.IPv4(172, 16, 1, 1), 5)
var testMarshalIPv4Addr4 = NewNodeIPAddr(net.IPv4(192, 168, 0, 3), 6)

var marshalIPv4SliceTests = []struct {
in CompactIPv4NodeAddrs
in CompactNodeAddrs
out []byte
panics bool
}{
{[]NodeAddr{{net.IP{172, 16, 1, 1}, 3}}, []byte{172, 16, 1, 1, 0, 3}, false},
{[]NodeAddr{{net.IPv4(172, 16, 1, 1), 4}}, []byte{172, 16, 1, 1, 0, 4}, false},
{[]NodeAddr{{net.IPv4(172, 16, 1, 1), 5}, {net.IPv4(192, 168, 0, 3), 6}}, []byte{
{[]NodeAddr{testMarshalIPv4Addr1}, []byte{172, 16, 1, 1, 0, 3}, false},
{[]NodeAddr{testMarshalIPv4Addr2}, []byte{172, 16, 1, 1, 0, 4}, false},
{[]NodeAddr{testMarshalIPv4Addr3, testMarshalIPv4Addr4}, []byte{
172, 16, 1, 1, 0, 5,
192, 168, 0, 3, 0, 6,
}, false},
{[]NodeAddr{{ParseIP("2001::1"), 7}}, nil, true},
{[]NodeAddr{{nil, 8}}, nil, true},
{[]NodeAddr{NewNodeIPAddr(ParseIP("2001::1"), 7)}, nil, true},
{[]NodeAddr{NewNodeIPAddr(nil, 8)}, nil, true},
}

func TestMarshalCompactIPv4NodeAddrs(t *testing.T) {
func TestMarshalIPv4CompactNodeAddrs(t *testing.T) {
for _, tc := range marshalIPv4SliceTests {
runFunc := assert.NotPanics
if tc.panics {
Expand Down
46 changes: 46 additions & 0 deletions krpc/i2p_utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package krpc

import (
"crypto/sha256"
"encoding/base32"
"encoding/base64"
)

var (
i2pB64enc *base64.Encoding = base64.NewEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-~")
i2pB32enc *base32.Encoding = base32.NewEncoding("abcdefghijklmnopqrstuvwxyz234567")
)

type I2PDest []byte

func (i2p I2PDest) String() string {
if len(i2p) == 32 {
b32addr := make([]byte, 56)
i2pB32enc.Encode(b32addr, i2p[:])

return string(b32addr[:52]) + ".b32.i2p"
}

buf := make([]byte, i2pB64enc.EncodedLen(len(i2p)))
i2pB64enc.Encode(buf, i2p)

return string(buf)
}

//Return a 32 byte representation of the destination
func (i2p I2PDest) Compact() I2PDest {
if len(i2p) == 32 {
return i2p
}

//invalid destination
if len(i2p) < 387 || len(i2p) > 475 {
return I2PDest{}
}

sum := sha256.Sum256(i2p)
addr := make(I2PDest, 32)
copy(addr[:], sum[:])

return addr
}
Loading