Add BuildResponseRecord
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-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-type:
|
test-i2np-type:
|
||||||
$(GO) test -v ./lib/i2np -run TestReadI2NPTypeWith
|
$(GO) test -v ./lib/i2np -run TestReadI2NPTypeWith
|
||||||
@ -21,10 +21,28 @@ test-i2np-data:
|
|||||||
test-i2np-regression:
|
test-i2np-regression:
|
||||||
$(GO) test -v ./lib/i2np -run TestCrasherRegression123781
|
$(GO) test -v ./lib/i2np -run TestCrasherRegression123781
|
||||||
|
|
||||||
|
test-i2np-build-request-record:
|
||||||
|
$(GO) test -v ./lib/i2np -run TestReadBuildRequestRecordReceiveTunnelTooLittleData
|
||||||
|
$(GO) test -v ./lib/i2np -run TestReadBuildRequestRecordReceiveTunnelValidData
|
||||||
|
$(GO) test -v ./lib/i2np -run TestReadBuildRequestRecordOurIdentTooLittleData
|
||||||
|
$(GO) test -v ./lib/i2np -run TestReadBuildRequestRecordOurIdentValidData
|
||||||
|
|
||||||
|
test-i2np-build-response-record:
|
||||||
|
$(GO) test -v ./lib/i2np -run TestReadBuildResponseRecordHashTooLittleData
|
||||||
|
$(GO) test -v ./lib/i2np -run TestReadBuildResponseRecordHashValidData
|
||||||
|
$(GO) test -v ./lib/i2np -run TestReadBuildResponseRecordRandomDataTooLittleData
|
||||||
|
$(GO) test -v ./lib/i2np -run TestReadBuildResponseRecordRandomDataValidData
|
||||||
|
$(GO) test -v ./lib/i2np -run TestReadBuildResponseRecordReplyTooLittleData
|
||||||
|
$(GO) test -v ./lib/i2np -run TestReadBuildResponseRecordReplyValidData
|
||||||
|
$(GO) test -v ./lib/i2np -run TestReadBuildResponseRecordTooLittleData
|
||||||
|
$(GO) test -v ./lib/i2np -run TestReadBuildResponseRecordValidData
|
||||||
|
|
||||||
.PHONY: test-i2np-header-all \
|
.PHONY: test-i2np-header-all \
|
||||||
test-i2np-type \
|
test-i2np-type \
|
||||||
test-i2np-message \
|
test-i2np-message \
|
||||||
test-i2np-expiration \
|
test-i2np-expiration \
|
||||||
test-i2np-ntcp-components \
|
test-i2np-ntcp-components \
|
||||||
test-i2np-data \
|
test-i2np-data \
|
||||||
test-i2np-regression
|
test-i2np-regression \
|
||||||
|
test-i2np-build-request-record \
|
||||||
|
test-i2np-build-response-record
|
||||||
|
@ -278,7 +278,7 @@ func readBuildRequestRecordReceiveTunnel(data []byte) (tunnel.TunnelID, error) {
|
|||||||
|
|
||||||
log.WithFields(logrus.Fields{
|
log.WithFields(logrus.Fields{
|
||||||
"at": "i2np.readBuildRequestRecordReceiveTunnel",
|
"at": "i2np.readBuildRequestRecordReceiveTunnel",
|
||||||
"receieve_tunnel": receive_tunnel,
|
"receive_tunnel": receive_tunnel,
|
||||||
}).Debug("parsed_build_request_record_receive_tunnel")
|
}).Debug("parsed_build_request_record_receive_tunnel")
|
||||||
return receive_tunnel, nil
|
return receive_tunnel, nil
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ func TestReadBuildRequestRecordReceiveTunnelValidData(t *testing.T) {
|
|||||||
assert.Equal(nil, err)
|
assert.Equal(nil, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReadBuildRequestRecordOurIdentTooLittleValidData(t *testing.T) {
|
func TestReadBuildRequestRecordOurIdentTooLittleData(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
receive_tunnel := []byte{0x00, 0x00, 0x00, 0x01}
|
receive_tunnel := []byte{0x00, 0x00, 0x00, 0x01}
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
package i2np
|
package i2np
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
common "github.com/go-i2p/go-i2p/lib/common/data"
|
common "github.com/go-i2p/go-i2p/lib/common/data"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
I2P I2NP BuildResponseRecord
|
I2P I2NP BuildResponseRecord
|
||||||
https://geti2p.net/spec/i2np
|
https://geti2p.net/spec/i2np#buildresponserecord
|
||||||
Accurate for version 0.9.28
|
Accurate for version 0.9.65
|
||||||
|
|
||||||
Encrypted:
|
Encrypted:
|
||||||
|
|
||||||
@ -43,8 +47,87 @@ type (
|
|||||||
BuildResponseRecordELGamal [528]byte
|
BuildResponseRecordELGamal [528]byte
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
BuildResponseRecord struct contains a response to BuildRequestRecord
|
||||||
|
concerning the creation of one hop in the tunnel
|
||||||
|
*/
|
||||||
type BuildResponseRecord struct {
|
type BuildResponseRecord struct {
|
||||||
Hash common.Hash
|
Hash common.Hash
|
||||||
Padding [495]byte
|
RandomData [495]byte
|
||||||
Reply byte
|
Reply byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ERR_BUILD_RESPONSE_RECORD_NOT_ENOUGH_DATA = errors.New("not enough i2np build request record data")
|
||||||
|
|
||||||
|
func ReadBuildResponseRecord(data []byte) (BuildResponseRecord, error) {
|
||||||
|
log.Debug("Reading BuildResponseRecord")
|
||||||
|
build_response_record := BuildResponseRecord{}
|
||||||
|
|
||||||
|
hash, err := readBuildResponseRecordHash(data)
|
||||||
|
if err != nil {
|
||||||
|
log.WithError(err).Error("Failed to read Hash")
|
||||||
|
return build_response_record, err
|
||||||
|
}
|
||||||
|
build_response_record.Hash = hash
|
||||||
|
|
||||||
|
random_data, err := readBuildResponseRecordRandomData(data)
|
||||||
|
if err != nil {
|
||||||
|
log.WithError(err).Error("Failed to read Random Data")
|
||||||
|
return build_response_record, err
|
||||||
|
}
|
||||||
|
build_response_record.RandomData = random_data
|
||||||
|
|
||||||
|
reply, err := readBuildResponseRecordReply(data)
|
||||||
|
if err != nil {
|
||||||
|
log.WithError(err).Error("Failed to read Reply")
|
||||||
|
return build_response_record, err
|
||||||
|
}
|
||||||
|
build_response_record.Reply = reply
|
||||||
|
|
||||||
|
log.Debug("BuildResponseRecord read successfully")
|
||||||
|
return build_response_record, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func readBuildResponseRecordHash(data []byte) (common.Hash, error) {
|
||||||
|
if len(data) < 32 {
|
||||||
|
return common.Hash{}, ERR_BUILD_REQUEST_RECORD_NOT_ENOUGH_DATA
|
||||||
|
}
|
||||||
|
|
||||||
|
hash := common.Hash(data[0:32])
|
||||||
|
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"at": "i2np.readBuildResponseRecordHash",
|
||||||
|
"hash": hash,
|
||||||
|
}).Debug("parsed_build_response_record_hash")
|
||||||
|
return hash, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func readBuildResponseRecordRandomData(data []byte) ([495]byte, error) {
|
||||||
|
if len(data) < 527 {
|
||||||
|
return [495]byte{}, ERR_BUILD_REQUEST_RECORD_NOT_ENOUGH_DATA
|
||||||
|
}
|
||||||
|
|
||||||
|
random_data := [495]byte{}
|
||||||
|
copy(random_data[:], data[32:527])
|
||||||
|
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"at": "i2np.readBuildResponseRandomData",
|
||||||
|
"random_data": random_data,
|
||||||
|
}).Debug("parsed_build_response_record_random_data")
|
||||||
|
return random_data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func readBuildResponseRecordReply(data []byte) (byte, error) {
|
||||||
|
if len(data) < 528 {
|
||||||
|
return byte(0), ERR_BUILD_REQUEST_RECORD_NOT_ENOUGH_DATA
|
||||||
|
}
|
||||||
|
|
||||||
|
reply := data[527]
|
||||||
|
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"at": "i2np.readBuildResponseReply",
|
||||||
|
"reply": reply,
|
||||||
|
}).Debug("parsed_build_response_record_reply")
|
||||||
|
return reply, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
117
lib/i2np/build_response_record_test.go
Normal file
117
lib/i2np/build_response_record_test.go
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
package i2np
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
common "github.com/go-i2p/go-i2p/lib/common/data"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestReadBuildResponseRecordHashTooLittleData(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
hash, err := readBuildResponseRecordHash([]byte{0x01})
|
||||||
|
assert.Equal(common.Hash{}, hash)
|
||||||
|
assert.Equal(ERR_BUILD_REQUEST_RECORD_NOT_ENOUGH_DATA, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadBuildResponseRecordHashValidData(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
data := make([]byte, 32)
|
||||||
|
data[31] = 0x31
|
||||||
|
res_hash, err := readBuildResponseRecordHash(data)
|
||||||
|
hash := common.Hash(data)
|
||||||
|
|
||||||
|
assert.Equal(res_hash, hash)
|
||||||
|
assert.Equal(nil, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadBuildResponseRecordRandomDataTooLittleData(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
hash := make([]byte, 32)
|
||||||
|
data := append(hash, 0x01)
|
||||||
|
random_data, err := readBuildResponseRecordRandomData(data)
|
||||||
|
assert.Equal([495]byte{}, random_data)
|
||||||
|
assert.Equal(ERR_BUILD_REQUEST_RECORD_NOT_ENOUGH_DATA, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadBuildResponseRecordRandomDataValidData(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
hash := make([]byte, 32)
|
||||||
|
hash[31] = 0x13
|
||||||
|
random_data := make([]byte, 495)
|
||||||
|
random_data[493] = 0x33
|
||||||
|
random_data[494] = 0x74
|
||||||
|
data := append(hash, random_data...)
|
||||||
|
res_random_data, err := readBuildResponseRecordRandomData(data)
|
||||||
|
assert.Equal([495]byte(random_data), res_random_data)
|
||||||
|
assert.Equal(nil, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadBuildResponseRecordReplyTooLittleData(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
hash := make([]byte, 32)
|
||||||
|
random_data := make([]byte, 495)
|
||||||
|
random_data[493] = 0x33
|
||||||
|
random_data[494] = 0x74
|
||||||
|
data := append(hash, random_data...)
|
||||||
|
|
||||||
|
res_reply, err := readBuildResponseRecordReply(data)
|
||||||
|
assert.Equal(byte(0), res_reply)
|
||||||
|
assert.Equal(ERR_BUILD_REQUEST_RECORD_NOT_ENOUGH_DATA, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func TestReadBuildResponseRecordReplyValidData(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
hash := make([]byte, 32)
|
||||||
|
hash[31] = 0x13
|
||||||
|
random_data := make([]byte, 495)
|
||||||
|
random_data[493] = 0x33
|
||||||
|
random_data[494] = 0x74
|
||||||
|
reply := byte(37)
|
||||||
|
data := append(hash, random_data...)
|
||||||
|
data = append(data, reply)
|
||||||
|
|
||||||
|
res_reply, err := readBuildResponseRecordReply(data)
|
||||||
|
assert.Equal(reply, res_reply)
|
||||||
|
assert.Equal(nil, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadBuildResponseRecordTooLittleData(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
hash := make([]byte, 32)
|
||||||
|
hash[31] = 0x31
|
||||||
|
data := append(hash, 0x01)
|
||||||
|
build_response_record, err := ReadBuildResponseRecord(data)
|
||||||
|
|
||||||
|
assert.Equal(common.Hash(hash), build_response_record.Hash)
|
||||||
|
assert.Equal([495]byte{}, build_response_record.RandomData)
|
||||||
|
assert.Equal(ERR_BUILD_REQUEST_RECORD_NOT_ENOUGH_DATA, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReadBuildResponseRecordValidData(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
hash := make([]byte, 32)
|
||||||
|
hash[31] = 0x12
|
||||||
|
random_data := make([]byte, 495)
|
||||||
|
random_data[493] = 0x33
|
||||||
|
random_data[494] = 0x74
|
||||||
|
reply := byte(37)
|
||||||
|
data := append(hash, random_data...)
|
||||||
|
data = append(data, reply)
|
||||||
|
|
||||||
|
build_response_record, err := ReadBuildResponseRecord(data)
|
||||||
|
|
||||||
|
assert.Equal(common.Hash(hash), build_response_record.Hash)
|
||||||
|
assert.Equal([495]byte(random_data), build_response_record.RandomData)
|
||||||
|
assert.Equal(reply, build_response_record.Reply)
|
||||||
|
assert.Equal(nil, err)
|
||||||
|
}
|
Reference in New Issue
Block a user