Skip to content

Commit

Permalink
Add magic value to encoded extensions to play nicely with other exten…
Browse files Browse the repository at this point in the history
…sions
  • Loading branch information
banks committed Nov 30, 2022
1 parent d654248 commit b690147
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 6 deletions.
18 changes: 12 additions & 6 deletions verifier/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package verifier

import (
"encoding/binary"
"errors"
"fmt"
"io"
"sync/atomic"
Expand Down Expand Up @@ -90,18 +91,23 @@ func (s *LogStore) StoreLog(log *raft.Log) error {
}

func encodeCheckpointMeta(startIdx, sum uint64) []byte {
var buf [16]byte
binary.LittleEndian.PutUint64(buf[0:8], startIdx)
binary.LittleEndian.PutUint64(buf[8:16], sum)
var buf [24]byte
binary.LittleEndian.PutUint64(buf[0:8], ExtensionMagicPrefix)
binary.LittleEndian.PutUint64(buf[8:16], startIdx)
binary.LittleEndian.PutUint64(buf[16:24], sum)
return buf[:]
}

func decodeCheckpointMeta(bs []byte) (startIdx, sum uint64, err error) {
if len(bs) < 16 {
if len(bs) < 24 {
return 0, 0, io.ErrShortBuffer
}
startIdx = binary.LittleEndian.Uint64(bs[0:8])
sum = binary.LittleEndian.Uint64(bs[8:16])
magic := binary.LittleEndian.Uint64(bs[0:8])
if magic != ExtensionMagicPrefix {
return 0, 0, errors.New("invalid extension data")
}
startIdx = binary.LittleEndian.Uint64(bs[8:16])
sum = binary.LittleEndian.Uint64(bs[16:24])
return startIdx, sum, nil
}

Expand Down
19 changes: 19 additions & 0 deletions verifier/verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,25 @@ import (
"github.com/segmentio/fasthash/fnv1a"
)

const (
// ExtensionMagicPrefix is the prefix we append to log Extensions fields to
// disambiguate from other middleware that may use extensions. This value is
// carefully constructed to be completely invalid as the beginning of a
// protobuf (3) wire protocol message since the other known user of this field
// encodes its data that way. If the first byte were 0xa8 this would be a
// valid protobuf field encoding for an int field, however currently the 3
// least significant bits encode the field type as 7, which is not a valid
// type in the current spec. Even if this does change in the future, the
// field's tag number encoded here is 123456789 so it's extremely unlikely
// that any valid protobuf schema will ever have enough fields or arbitrarily
// decide to assign field tags that large (though unrecognized tags would be
// ignored on decode). Finally, the value of the field is the varint encoding
// of the randomly chosen value 53906 so if type 7 is ever valid in the future
// and used as a length-prefixed type, the length decoded would be way longer
// than the buffer making it invalid.
ExtensionMagicPrefix uint64 = 0xafd1f9d60392a503
)

// IsCheckpointFn is a function that can decide whether the contents of a raft
// log's Data represents a checkpoint message. It is called on every append so
// it must be relatively fast in the common case. If it returns true for a log,
Expand Down

0 comments on commit b690147

Please sign in to comment.