mirror of
https://github.com/go-i2p/go-i2p.git
synced 2025-06-07 10:01:41 -04:00
Add DatabaseLookup and test it
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
|
||||
test-i2np-header-all: test-i2np-type test-i2np-message test-i2np-expiration test-i2np-ntcp-components test-i2np-data test-i2np-regression test-i2np-build-request-record test-i2np-build-response-record
|
||||
test-i2np-header-all: test-i2np-type test-i2np-message test-i2np-expiration test-i2np-ntcp-components test-i2np-data test-i2np-regression test-i2np-build-request-record test-i2np-build-response-record test-i2np-database-lookup
|
||||
|
||||
test-i2np-type:
|
||||
$(GO) test -v ./lib/i2np -run TestReadI2NPTypeWith
|
||||
@ -37,6 +37,31 @@ test-i2np-build-response-record:
|
||||
$(GO) test -v ./lib/i2np -run TestReadBuildResponseRecordTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadBuildResponseRecordValidData
|
||||
|
||||
test-i2np-database-lookup:
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupKeyTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupKeyValidData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupFromTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupFromValidData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupFlagsTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupFlagsValidData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupReplyTunnelIDTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupReplyTunnelIDNotIncluded
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupReplyTunnelIDValidData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupSizeTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupSizeValidData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupExcludedPeersTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupExcludedPeersZeroSize
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupExcludedPeersValidData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupReplyKeyTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupReplyKeyValidData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupTagsTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupTagsValidData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupReplyTagsTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupReplyTagsZeroTags
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupReplyTagsValidData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupTooLittleData
|
||||
$(GO) test -v ./lib/i2np -run TestReadDatabaseLookupValidData
|
||||
|
||||
.PHONY: test-i2np-header-all \
|
||||
test-i2np-type \
|
||||
test-i2np-message \
|
||||
@ -45,4 +70,5 @@ test-i2np-build-response-record:
|
||||
test-i2np-data \
|
||||
test-i2np-regression \
|
||||
test-i2np-build-request-record \
|
||||
test-i2np-build-response-record
|
||||
test-i2np-build-response-record \
|
||||
test-i2np-database-lookup
|
||||
|
@ -1,6 +1,10 @@
|
||||
package i2np
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
common "github.com/go-i2p/go-i2p/lib/common/data"
|
||||
"github.com/go-i2p/go-i2p/lib/common/session_key"
|
||||
"github.com/go-i2p/go-i2p/lib/common/session_tag"
|
||||
@ -8,8 +12,8 @@ import (
|
||||
|
||||
/*
|
||||
I2P I2NP DatabaseLookup
|
||||
https://geti2p.net/spec/i2np
|
||||
Accurate for version 0.9.28
|
||||
https://geti2p.net/spec/i2np#databaselookup
|
||||
Accurate for version 0.9.65
|
||||
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| SHA256 hash as the key to look up |
|
||||
@ -21,7 +25,7 @@ Accurate for version 0.9.28
|
||||
| |
|
||||
+----+----+----+----+----+----+----+----+
|
||||
| SHA256 hash of the routerInfo |
|
||||
+ who is asking, or the gateway to +
|
||||
+ who is asking or the gateway to +
|
||||
| send the reply to |
|
||||
+ +
|
||||
| |
|
||||
@ -30,7 +34,7 @@ Accurate for version 0.9.28
|
||||
+----+----+----+----+----+----+----+----+
|
||||
|flag| reply_tunnelId | size | |
|
||||
+----+----+----+----+----+----+----+ +
|
||||
| SHA256 of $key1 to exclude |
|
||||
| SHA256 of key1 to exclude |
|
||||
+ +
|
||||
| |
|
||||
+ +
|
||||
@ -38,7 +42,7 @@ Accurate for version 0.9.28
|
||||
+ +----+
|
||||
| | |
|
||||
+----+----+----+----+----+----+----+ +
|
||||
| SHA256 of $key2 to exclude |
|
||||
| SHA256 of key2 to exclude |
|
||||
+ +
|
||||
~ ~
|
||||
+ +----+
|
||||
@ -95,12 +99,20 @@ flags ::
|
||||
with version 0.9.16 or higher.
|
||||
01 => LS lookup, return LeaseSet or
|
||||
DatabaseSearchReplyMessage
|
||||
As of release 0.9.38, may also return a
|
||||
LeaseSet2, MetaLeaseSet, or EncryptedLeaseSet.
|
||||
10 => RI lookup, return RouterInfo or
|
||||
DatabaseSearchReplyMessage
|
||||
11 => exploration lookup, return DatabaseSearchReplyMessage
|
||||
containing non-floodfill routers only (replaces an
|
||||
excludedPeer of all zeroes)
|
||||
bits 7-4:
|
||||
bit 4: ECIESFlag
|
||||
before release 0.9.46 ignored
|
||||
as of release 0.9.46:
|
||||
0 => send unencrypted or ElGamal reply
|
||||
1 => send ChaCha/Poly encrypted reply using enclosed key
|
||||
(whether tag is enclosed depends on bit 1)
|
||||
bits 7-5:
|
||||
through release 0.9.5, must be set to 0
|
||||
as of release 0.9.6, ignored, set to 0 for compatibility with
|
||||
future uses and with older routers
|
||||
@ -108,7 +120,7 @@ flags ::
|
||||
reply_tunnelId ::
|
||||
4 byte TunnelID
|
||||
only included if deliveryFlag == 1
|
||||
tunnelId of the tunnel to send the reply to
|
||||
tunnelId of the tunnel to send the reply to, nonzero
|
||||
|
||||
size ::
|
||||
2 byte Integer
|
||||
@ -124,18 +136,53 @@ excludedPeers ::
|
||||
to list non-floodfill routers only.
|
||||
|
||||
reply_key ::
|
||||
32 byte SessionKey
|
||||
only included if encryptionFlag == 1, only as of release 0.9.7
|
||||
32 byte key
|
||||
see below
|
||||
|
||||
tags ::
|
||||
1 byte Integer
|
||||
valid range: 1-32 (typically 1)
|
||||
the number of reply tags that follow
|
||||
only included if encryptionFlag == 1, only as of release 0.9.7
|
||||
see below
|
||||
|
||||
reply_tags ::
|
||||
one or more 8 or 32 byte session tags (typically one)
|
||||
see below
|
||||
|
||||
|
||||
ElG to ElG
|
||||
|
||||
reply_key ::
|
||||
32 byte SessionKey big-endian
|
||||
only included if encryptionFlag == 1 AND ECIESFlag == 0, only as of release 0.9.7
|
||||
|
||||
tags ::
|
||||
1 byte Integer
|
||||
valid range: 1-32 (typically 1)
|
||||
the number of reply tags that follow
|
||||
only included if encryptionFlag == 1 AND ECIESFlag == 0, only as of release 0.9.7
|
||||
|
||||
reply_tags ::
|
||||
one or more 32 byte SessionTags (typically one)
|
||||
only included if encryptionFlag == 1, only as of release 0.9.7
|
||||
only included if encryptionFlag == 1 AND ECIESFlag == 0, only as of release 0.9.7
|
||||
|
||||
|
||||
ECIES to ElG
|
||||
|
||||
reply_key ::
|
||||
32 byte ECIES SessionKey big-endian
|
||||
only included if encryptionFlag == 0 AND ECIESFlag == 1, only as of release 0.9.46
|
||||
|
||||
tags ::
|
||||
1 byte Integer
|
||||
required value: 1
|
||||
the number of reply tags that follow
|
||||
only included if encryptionFlag == 0 AND ECIESFlag == 1, only as of release 0.9.46
|
||||
|
||||
reply_tags ::
|
||||
an 8 byte ECIES SessionTag
|
||||
only included if encryptionFlag == 0 AND ECIESFlag == 1, only as of release 0.9.46
|
||||
|
||||
*/
|
||||
|
||||
type DatabaseLookup struct {
|
||||
@ -146,6 +193,209 @@ type DatabaseLookup struct {
|
||||
Size int
|
||||
ExcludedPeers []common.Hash
|
||||
ReplyKey session_key.SessionKey
|
||||
tags int
|
||||
Tags int
|
||||
ReplyTags []session_tag.SessionTag
|
||||
}
|
||||
|
||||
var ERR_DATABASE_LOOKUP_NOT_ENOUGH_DATA = errors.New("not enough i2np database lookup data")
|
||||
|
||||
func ReadDatabaseLookup(data []byte) (DatabaseLookup, error) {
|
||||
log.Debug("Reading DatabaseLookup")
|
||||
databaseLookup := DatabaseLookup{}
|
||||
|
||||
length, key, err := readDatabaseLookupKey(data)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Failed to read Key")
|
||||
return databaseLookup, err
|
||||
}
|
||||
databaseLookup.Key = key
|
||||
|
||||
length, from, err := readDatabaseLookupFrom(length, data)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Failed to read From")
|
||||
return databaseLookup, err
|
||||
}
|
||||
databaseLookup.From = from
|
||||
|
||||
length, flags, err := readDatabaseLookupFlags(length, data)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Failed to read Flags")
|
||||
return databaseLookup, err
|
||||
}
|
||||
databaseLookup.Flags = flags
|
||||
|
||||
length, replyTunnelID, err := readDatabaseLookupReplyTunnelID(flags, length, data)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Failed to read ReplyTunnelID")
|
||||
return databaseLookup, err
|
||||
}
|
||||
databaseLookup.ReplyTunnelID = replyTunnelID
|
||||
|
||||
length, size, err := readDatabaseLookupSize(length, data)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Failed to read Size")
|
||||
return databaseLookup, err
|
||||
}
|
||||
databaseLookup.Size = size
|
||||
|
||||
length, excludedPeers, err := readDatabaseLookupExcludedPeers(length, data, size)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Failed to read ExcludedPeers")
|
||||
return databaseLookup, err
|
||||
}
|
||||
databaseLookup.ExcludedPeers = excludedPeers
|
||||
|
||||
length, reply_key, err := readDatabaseLookupReplyKey(length, data)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Failed to read ReplyKey")
|
||||
return databaseLookup, err
|
||||
}
|
||||
databaseLookup.ReplyKey = reply_key
|
||||
|
||||
length, tags, err := readDatabaseLookupTags(length, data)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Failed to read Tags")
|
||||
return databaseLookup, err
|
||||
}
|
||||
databaseLookup.Tags = tags
|
||||
|
||||
length, reply_tags, err := readDatabaseLookupReplyTags(length, data, tags)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Failed to read ReplyTags")
|
||||
return databaseLookup, err
|
||||
}
|
||||
databaseLookup.ReplyTags = reply_tags
|
||||
|
||||
log.Debug("DatabaseLookup read successfully")
|
||||
return databaseLookup, nil
|
||||
}
|
||||
|
||||
func readDatabaseLookupKey(data []byte) (int, common.Hash, error) {
|
||||
if len(data) < 32 {
|
||||
return 0, common.Hash{}, ERR_DATABASE_LOOKUP_NOT_ENOUGH_DATA
|
||||
}
|
||||
|
||||
key := common.Hash(data[:32])
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "i2np.readDatabaseLookupKey",
|
||||
"key": key,
|
||||
}).Debug("parsed_database_lookup_key")
|
||||
return 32, key, nil
|
||||
}
|
||||
|
||||
func readDatabaseLookupFrom(length int, data []byte) (int, common.Hash, error) {
|
||||
if len(data) < length + 32 {
|
||||
return length, common.Hash{}, ERR_DATABASE_LOOKUP_NOT_ENOUGH_DATA
|
||||
}
|
||||
|
||||
from := common.Hash(data[length:length + 32])
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "i2np.database_lookup.readDatabaseLookupFrom",
|
||||
"from": from,
|
||||
}).Debug("parsed_database_lookup_from")
|
||||
return length + 32, from, nil
|
||||
}
|
||||
|
||||
func readDatabaseLookupFlags(length int, data []byte) (int, byte, error) {
|
||||
if len(data) < length + 1 {
|
||||
return length, byte(0), ERR_DATABASE_LOOKUP_NOT_ENOUGH_DATA
|
||||
}
|
||||
flags := data[length]
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "i2np.database_lookup.readDatabaseLookupFlags",
|
||||
"flags": flags,
|
||||
}).Debug("parsed_database_lookup_flags")
|
||||
return length + 1, flags, nil
|
||||
}
|
||||
|
||||
func readDatabaseLookupReplyTunnelID(flags byte, length int, data []byte) (int, [4]byte, error) {
|
||||
if flags & 1 != 1 {
|
||||
return length, [4]byte{}, nil
|
||||
}
|
||||
if len(data) < length + 4 {
|
||||
return length, [4]byte{}, ERR_DATABASE_LOOKUP_NOT_ENOUGH_DATA
|
||||
}
|
||||
|
||||
replyTunnelID := [4]byte(data[length:length + 4])
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "i2np.database_lookup.readDatabaseLookupReplyTunnelID",
|
||||
"reply_tunnel_id": replyTunnelID,
|
||||
}).Debug("parsed_database_lookup_reply_tunnel_id")
|
||||
return length + 4, replyTunnelID, nil
|
||||
}
|
||||
|
||||
func readDatabaseLookupSize(length int, data []byte) (int, int, error) {
|
||||
if len(data) < length + 2 {
|
||||
return length, 0, ERR_DATABASE_LOOKUP_NOT_ENOUGH_DATA
|
||||
}
|
||||
|
||||
size := common.Integer(data[length:length + 2]).Int()
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "i2np.database_lookup.readDatabaseLookupSize",
|
||||
"size": size,
|
||||
}).Debug("parsed_database_lookup_size")
|
||||
return length + 2, size, nil
|
||||
}
|
||||
|
||||
func readDatabaseLookupExcludedPeers(length int, data []byte, size int) (int, []common.Hash, error) {
|
||||
if len(data) < length + size * 32 {
|
||||
return length, []common.Hash{}, ERR_DATABASE_LOOKUP_NOT_ENOUGH_DATA
|
||||
}
|
||||
var excludedPeers []common.Hash
|
||||
for i := 0; i < size; i++ {
|
||||
offset := length + i * 32
|
||||
peer := common.Hash(data[offset:offset + 32])
|
||||
excludedPeers = append(excludedPeers, peer)
|
||||
}
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "i2np.database_lookup.readDatabaseLookupExcludedPeers",
|
||||
"excluded_peers": excludedPeers,
|
||||
}).Debug("parsed_database_lookup_excluded_peers")
|
||||
return length + size * 32, excludedPeers, nil
|
||||
}
|
||||
|
||||
func readDatabaseLookupReplyKey(length int, data []byte) (int, session_key.SessionKey, error) {
|
||||
if len(data) < length + 32 {
|
||||
return length, session_key.SessionKey{}, ERR_DATABASE_LOOKUP_NOT_ENOUGH_DATA
|
||||
}
|
||||
replyKey := session_key.SessionKey(data[length:length + 32])
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "i2np.database_lookup.readDatabaseLookupReplyKey",
|
||||
"reply_key": replyKey,
|
||||
}).Debug("parsed_database_lookup_reply_key")
|
||||
return length + 32, replyKey, nil
|
||||
}
|
||||
|
||||
func readDatabaseLookupTags(length int, data []byte) (int, int, error) {
|
||||
if len(data) < length + 1 {
|
||||
return length, 0, ERR_DATABASE_LOOKUP_NOT_ENOUGH_DATA
|
||||
}
|
||||
tags := int(data[length])
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "i2np.database_lookup.readDatabaseLookupTags",
|
||||
"tags": tags,
|
||||
}).Debug("parsed_database_lookup_tags")
|
||||
return length + 1, tags, nil
|
||||
}
|
||||
|
||||
func readDatabaseLookupReplyTags(length int, data []byte, tags int) (int, []session_tag.SessionTag, error) {
|
||||
if len(data) < length + tags * 32 {
|
||||
return length, []session_tag.SessionTag{}, ERR_DATABASE_LOOKUP_NOT_ENOUGH_DATA
|
||||
}
|
||||
var reply_tags []session_tag.SessionTag
|
||||
for i := 0; i < tags; i++ {
|
||||
offset := length + i * 32
|
||||
tag := session_tag.SessionTag(data[offset:offset + 32])
|
||||
reply_tags = append(reply_tags, tag)
|
||||
}
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"at": "i2np.database_lookup.readDatabaseLookupReplyTags",
|
||||
"reply_tags": reply_tags,
|
||||
}).Debug("parsed_database_lookup_reply_tags")
|
||||
return length + tags * 32, reply_tags, nil
|
||||
}
|
||||
|
430
lib/i2np/database_lookup_test.go
Normal file
430
lib/i2np/database_lookup_test.go
Normal file
@ -0,0 +1,430 @@
|
||||
package i2np
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
common "github.com/go-i2p/go-i2p/lib/common/data"
|
||||
"github.com/go-i2p/go-i2p/lib/common/session_key"
|
||||
"github.com/go-i2p/go-i2p/lib/common/session_tag"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestReadDatabaseLookupKeyTooLittleData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
length, key, err := readDatabaseLookupKey([]byte{0x01})
|
||||
assert.Equal(0, length)
|
||||
assert.Equal(common.Hash{}, key)
|
||||
assert.Equal(ERR_DATABASE_LOOKUP_NOT_ENOUGH_DATA, err)
|
||||
}
|
||||
|
||||
func TestReadDatabaseLookupKeyValidData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
data := make([]byte, 32)
|
||||
for i := range 31 {
|
||||
data[i] = 0x31
|
||||
}
|
||||
length, key, err := readDatabaseLookupKey(data)
|
||||
expected := common.Hash(data)
|
||||
|
||||
assert.Equal(32, length)
|
||||
assert.Equal(expected, key)
|
||||
assert.Equal(nil, err)
|
||||
}
|
||||
|
||||
func TestReadDatabaseLookupFromTooLittleData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
length := 32
|
||||
prev := make([]byte, length)
|
||||
data := append(prev, 0x01)
|
||||
|
||||
length, key, err := readDatabaseLookupFrom(length, data)
|
||||
assert.Equal(32, length)
|
||||
assert.Equal(common.Hash{}, key)
|
||||
assert.Equal(ERR_DATABASE_LOOKUP_NOT_ENOUGH_DATA, err)
|
||||
}
|
||||
|
||||
func TestReadDatabaseLookupFromValidData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
length := 32
|
||||
prev := make([]byte, length)
|
||||
expectedFrom := make([]byte, 32)
|
||||
expectedFrom[23] = 0x21
|
||||
expectedFrom[29] = 0x37
|
||||
data := append(prev, expectedFrom...)
|
||||
length, from, err := readDatabaseLookupFrom(length, data)
|
||||
expected := common.Hash(expectedFrom)
|
||||
|
||||
assert.Equal(64, length)
|
||||
assert.Equal(from, expected)
|
||||
assert.Equal(nil, err)
|
||||
}
|
||||
|
||||
func TestReadDatabaseLookupFlagsTooLittleData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
length := 64
|
||||
prev := make([]byte, length)
|
||||
data := prev
|
||||
|
||||
length, flags, err := readDatabaseLookupFlags(length, data)
|
||||
assert.Equal(64, length)
|
||||
assert.Equal(byte(0), flags)
|
||||
assert.Equal(ERR_DATABASE_LOOKUP_NOT_ENOUGH_DATA, err)
|
||||
}
|
||||
|
||||
func TestReadDatabaseLookupFlagsValidData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
length := 64
|
||||
prev := make([]byte, length)
|
||||
expected := byte(0x1)
|
||||
data := append(prev, expected)
|
||||
length, flags, err := readDatabaseLookupFlags(length, data)
|
||||
|
||||
assert.Equal(65, length)
|
||||
assert.Equal(flags, expected)
|
||||
assert.Equal(nil, err)
|
||||
}
|
||||
func TestReadDatabaseLookupReplyTunnelIDTooLittleData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
length := 64
|
||||
prev := make([]byte, length)
|
||||
flag := byte(0x1)
|
||||
data := append(prev, flag)
|
||||
|
||||
excessData := make([]byte, 2)
|
||||
excessData[1] = 0x32
|
||||
data = append(data, excessData...)
|
||||
length, flags, err := readDatabaseLookupFlags(length, data)
|
||||
|
||||
length, replyTunnelID, err := readDatabaseLookupReplyTunnelID(flags, length, data)
|
||||
assert.Equal(65, length)
|
||||
assert.Equal([4]byte{}, replyTunnelID)
|
||||
assert.Equal(ERR_DATABASE_LOOKUP_NOT_ENOUGH_DATA, err)
|
||||
}
|
||||
|
||||
func TestReadDatabaseLookupReplyTunnelIDNotIncluded(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
length := 65
|
||||
data := make([]byte, length)
|
||||
length, flags, err := readDatabaseLookupFlags(length, data)
|
||||
|
||||
length, tunnelID, err := readDatabaseLookupReplyTunnelID(flags, length, data)
|
||||
assert.Equal(65, length)
|
||||
assert.Equal([4]byte{}, tunnelID)
|
||||
assert.Equal(nil, err)
|
||||
}
|
||||
|
||||
func TestReadDatabaseLookupReplyTunnelIDValidData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
length := 64
|
||||
prev := make([]byte, length)
|
||||
flag := byte(0x1)
|
||||
data := append(prev, flag)
|
||||
|
||||
expected := make([]byte, 4)
|
||||
expected[1] = 0x32
|
||||
expected[3] = 0x34
|
||||
data = append(data, expected...)
|
||||
length, flags, err := readDatabaseLookupFlags(length, data)
|
||||
|
||||
length, replyTunnelID, err := readDatabaseLookupReplyTunnelID(flags, length, data)
|
||||
assert.Equal(69, length)
|
||||
assert.Equal([4]byte(expected), replyTunnelID)
|
||||
assert.Equal(nil, err)
|
||||
}
|
||||
|
||||
func TestReadDatabaseLookupSizeTooLittleData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
length := 65
|
||||
data := make([]byte, length)
|
||||
data = append(data, 0x2)
|
||||
|
||||
length, size, err := readDatabaseLookupSize(length, data)
|
||||
assert.Equal(65, length)
|
||||
assert.Equal(0, size)
|
||||
assert.Equal(ERR_DATABASE_LOOKUP_NOT_ENOUGH_DATA, err)
|
||||
}
|
||||
|
||||
func TestReadDatabaseLookupSizeValidData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
length := 65
|
||||
data := make([]byte, length)
|
||||
expectedSizeData := []byte{0x16,0x9}
|
||||
data = append(data, expectedSizeData...)
|
||||
|
||||
length, size, err := readDatabaseLookupSize(length, data)
|
||||
assert.Equal(67, length)
|
||||
assert.Equal(common.Integer(expectedSizeData).Int(), size)
|
||||
assert.Equal(nil, err)
|
||||
}
|
||||
|
||||
func TestReadDatabaseLookupExcludedPeersTooLittleData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
length := 65
|
||||
data := make([]byte, length)
|
||||
sizeData := []byte{0x0,0x3}
|
||||
data = append(data, sizeData...)
|
||||
data = append(data, 0x23)
|
||||
|
||||
length, size, err := readDatabaseLookupSize(length, data)
|
||||
length, excludedPeers, err := readDatabaseLookupExcludedPeers(length, data, size)
|
||||
assert.Equal([]common.Hash{}, excludedPeers)
|
||||
assert.Equal(67, length)
|
||||
assert.Equal(ERR_DATABASE_LOOKUP_NOT_ENOUGH_DATA, err)
|
||||
}
|
||||
|
||||
func TestReadDatabaseLookupExcludedPeersZeroSize(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
length := 65
|
||||
data := make([]byte, length)
|
||||
sizeData := []byte{0x0,0x0}
|
||||
data = append(data, sizeData...)
|
||||
data = append(data, 0x23)
|
||||
|
||||
length, size, err := readDatabaseLookupSize(length, data)
|
||||
|
||||
var expectedExcludedPeers []common.Hash
|
||||
|
||||
length, excludedPeers, err := readDatabaseLookupExcludedPeers(length, data, size)
|
||||
assert.Equal(expectedExcludedPeers, excludedPeers)
|
||||
assert.Equal(67, length)
|
||||
assert.Equal(nil, err)
|
||||
}
|
||||
|
||||
func TestReadDatabaseLookupExcludedPeersValidData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
length := 65
|
||||
data := make([]byte, length)
|
||||
sizeData := []byte{0x0,0x3}
|
||||
data = append(data, sizeData...)
|
||||
|
||||
length, size, err := readDatabaseLookupSize(length, data)
|
||||
|
||||
var expectedExcludedPeers []common.Hash
|
||||
for i := range size {
|
||||
peer := make([]byte, 32)
|
||||
// random data:
|
||||
peer[i + 1] = 0x43
|
||||
peer[i + 23] = 0x89
|
||||
expectedExcludedPeers = append(expectedExcludedPeers, common.Hash(peer))
|
||||
data = append(data, peer...)
|
||||
}
|
||||
|
||||
length, excludedPeers, err := readDatabaseLookupExcludedPeers(length, data, size)
|
||||
assert.Equal(expectedExcludedPeers, excludedPeers)
|
||||
assert.Equal(67 + 32 * size, length)
|
||||
assert.Equal(nil, err)
|
||||
}
|
||||
|
||||
func TestReadDatabaseLookupReplyKeyTooLittleData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
length := 67
|
||||
data := make([]byte, length)
|
||||
data = append(data, 0x2)
|
||||
|
||||
length, replyKey, err := readDatabaseLookupReplyKey(length, data)
|
||||
assert.Equal(67, length)
|
||||
assert.Equal(session_key.SessionKey{}, replyKey)
|
||||
assert.Equal(ERR_DATABASE_LOOKUP_NOT_ENOUGH_DATA, err)
|
||||
}
|
||||
|
||||
func TestReadDatabaseLookupReplyKeyValidData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
length := 67
|
||||
data := make([]byte, length)
|
||||
expectedReplyKeyData := make([]byte, 32)
|
||||
expectedReplyKeyData[3] = 0x31
|
||||
expectedReplyKey := session_key.SessionKey(expectedReplyKeyData)
|
||||
data = append(data, expectedReplyKeyData...)
|
||||
|
||||
length, replyKey, err := readDatabaseLookupReplyKey(length, data)
|
||||
assert.Equal(67 + 32, length)
|
||||
assert.Equal(expectedReplyKey, replyKey)
|
||||
assert.Equal(nil, err)
|
||||
}
|
||||
|
||||
func TestReadDatabaseLookupTagsTooLittleData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
length := 99
|
||||
data := make([]byte, length)
|
||||
|
||||
length, tags, err := readDatabaseLookupTags(length, data)
|
||||
assert.Equal(99, length)
|
||||
assert.Equal(0, tags)
|
||||
assert.Equal(ERR_DATABASE_LOOKUP_NOT_ENOUGH_DATA, err)
|
||||
}
|
||||
|
||||
func TestReadDatabaseLookupTagsValidData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
length := 99
|
||||
data := make([]byte, length)
|
||||
expected := 121
|
||||
data = append(data, byte(expected))
|
||||
|
||||
length, tags, err := readDatabaseLookupTags(length, data)
|
||||
assert.Equal(100, length)
|
||||
assert.Equal(expected, tags)
|
||||
assert.Equal(nil, err)
|
||||
}
|
||||
|
||||
func TestReadDatabaseLookupReplyTagsTooLittleData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
length := 99
|
||||
data := make([]byte, length)
|
||||
tags := 10
|
||||
data = append(data, byte(tags))
|
||||
data = append(data, 0x34)
|
||||
|
||||
length, tags, err := readDatabaseLookupTags(length, data)
|
||||
length, replyTags, err := readDatabaseLookupReplyTags(length, data, tags)
|
||||
assert.Equal(100, length)
|
||||
assert.Equal([]session_tag.SessionTag{}, replyTags)
|
||||
assert.Equal(ERR_DATABASE_LOOKUP_NOT_ENOUGH_DATA, err)
|
||||
}
|
||||
|
||||
func TestReadDatabaseLookupReplyTagsZeroTags(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
length := 99
|
||||
data := make([]byte, length)
|
||||
tags := 0
|
||||
data = append(data, byte(tags))
|
||||
data = append(data, 0x23)
|
||||
|
||||
length, tags, err := readDatabaseLookupTags(length, data)
|
||||
|
||||
var expectedReplyTags []session_tag.SessionTag
|
||||
|
||||
length, replyTags, err := readDatabaseLookupReplyTags(length, data, tags)
|
||||
assert.Equal(expectedReplyTags, replyTags)
|
||||
assert.Equal(100, length)
|
||||
assert.Equal(nil, err)
|
||||
}
|
||||
|
||||
func TestReadDatabaseLookupReplyTagsValidData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
length := 99
|
||||
data := make([]byte, length)
|
||||
tags := 10
|
||||
data = append(data, byte(tags))
|
||||
|
||||
length, tags, err := readDatabaseLookupTags(length, data)
|
||||
|
||||
var expectedReplyTags []session_tag.SessionTag
|
||||
for i := range tags {
|
||||
tag := make([]byte, 32)
|
||||
// random data:
|
||||
tag[i + 1] = 0x43
|
||||
tag[i + 5] = 0x89
|
||||
expectedReplyTags = append(expectedReplyTags, session_tag.SessionTag(tag))
|
||||
data = append(data, tag...)
|
||||
}
|
||||
|
||||
length, replyTags, err := readDatabaseLookupReplyTags(length, data, tags)
|
||||
assert.Equal(expectedReplyTags, replyTags)
|
||||
assert.Equal(100 + 32 * tags, length)
|
||||
assert.Equal(nil, err)
|
||||
}
|
||||
|
||||
func TestReadDatabaseLookupTooLittleData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
length := 67
|
||||
data := make([]byte, length)
|
||||
expectedReplyKeyData := make([]byte, 32)
|
||||
expectedReplyKeyData[3] = 0x31
|
||||
expectedReplyKey := session_key.SessionKey(expectedReplyKeyData)
|
||||
data = append(data, expectedReplyKeyData...)
|
||||
|
||||
databaseLookup, err := ReadDatabaseLookup(data)
|
||||
assert.Equal(expectedReplyKey, databaseLookup.ReplyKey)
|
||||
assert.Equal(ERR_DATABASE_LOOKUP_NOT_ENOUGH_DATA, err)
|
||||
}
|
||||
|
||||
func TestReadDatabaseLookupValidData(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
data := make([]byte, 32)
|
||||
for i := range 31 {
|
||||
data[i] = 0x31
|
||||
}
|
||||
expectedKey := common.Hash(data)
|
||||
|
||||
from := make([]byte, 32)
|
||||
from[14] = 0x69
|
||||
from[27] = 0x15
|
||||
data = append(data, from...)
|
||||
expectedFrom := common.Hash(from)
|
||||
|
||||
expectedFlags := byte(0x1)
|
||||
data = append(data, expectedFlags)
|
||||
|
||||
tunnelIDData := make([]byte, 4)
|
||||
tunnelIDData[0] = 0xff
|
||||
tunnelIDData[2] = 0xf2
|
||||
data = append(data, tunnelIDData...)
|
||||
expectedTunnelID := [4]byte(tunnelIDData)
|
||||
|
||||
sizeData := []byte{0x0,0xf}
|
||||
data = append(data, sizeData...)
|
||||
expectedSize := common.Integer(sizeData).Int()
|
||||
|
||||
var expectedExcludedPeers []common.Hash
|
||||
for i := range expectedSize {
|
||||
peer := make([]byte, 32)
|
||||
// random data:
|
||||
peer[i + 5] = 0xdd
|
||||
peer[i + 13] = 0x35
|
||||
expectedExcludedPeers = append(expectedExcludedPeers, common.Hash(peer))
|
||||
data = append(data, peer...)
|
||||
}
|
||||
|
||||
replyKeyData := make([]byte, 32)
|
||||
replyKeyData[6] = 0x11
|
||||
replyKeyData[14] = 0x13
|
||||
data = append(data, replyKeyData...)
|
||||
expectedReplyKey := session_key.SessionKey(replyKeyData)
|
||||
|
||||
expectedTags := 15
|
||||
data = append(data, byte(expectedTags))
|
||||
|
||||
var expectedReplyTags []session_tag.SessionTag
|
||||
for i := range expectedTags {
|
||||
tag := make([]byte, 32)
|
||||
// random data:
|
||||
tag[i + 3] = 0x22
|
||||
tag[i + 13] = 0x11
|
||||
expectedReplyTags = append(expectedReplyTags, session_tag.SessionTag(tag))
|
||||
data = append(data, tag...)
|
||||
}
|
||||
databaseLookup, err := ReadDatabaseLookup(data)
|
||||
assert.Equal(expectedKey, databaseLookup.Key)
|
||||
assert.Equal(expectedFrom, databaseLookup.From)
|
||||
assert.Equal(expectedFlags, databaseLookup.Flags)
|
||||
assert.Equal(expectedTunnelID, databaseLookup.ReplyTunnelID)
|
||||
assert.Equal(expectedSize, databaseLookup.Size)
|
||||
assert.Equal(expectedExcludedPeers, databaseLookup.ExcludedPeers)
|
||||
assert.Equal(expectedReplyKey, databaseLookup.ReplyKey)
|
||||
assert.Equal(expectedTags, databaseLookup.Tags)
|
||||
assert.Equal(expectedReplyTags, databaseLookup.ReplyTags)
|
||||
assert.Equal(err, nil)
|
||||
}
|
Reference in New Issue
Block a user