Add BuildResponseRecord

This commit is contained in:
satk0
2024-12-18 13:17:42 +01:00
parent 6b2f231c36
commit 9591f496eb
5 changed files with 227 additions and 9 deletions

View File

@ -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

View File

@ -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
} }

View File

@ -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}

View File

@ -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
}

View 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)
}