1
0

wirecodec.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. // Package wirecodec holds the shared envelope codec for node-to-node config
  2. // transport: zstd (de)compression, SHA-256 integrity hashing, and the header /
  3. // capability constants both the panel (sender) and node (receiver) agree on.
  4. package wirecodec
  5. import (
  6. "crypto/sha256"
  7. "encoding/hex"
  8. "errors"
  9. "github.com/klauspost/compress/zstd"
  10. )
  11. const (
  12. // HashHeader carries the lowercase-hex SHA-256 of the (uncompressed) body.
  13. HashHeader = "X-Config-Sha256"
  14. // CapsHeader is set by a node on its API responses to advertise support.
  15. CapsHeader = "X-3x-Node-Caps"
  16. // EncodingZstd is the Content-Encoding value for a zstd-compressed body.
  17. EncodingZstd = "zstd"
  18. // CapZstd is the capability token advertised in CapsHeader.
  19. CapZstd = "zstd"
  20. // maxDecodeBytes bounds in-memory decompression to defuse a zstd bomb from
  21. // an (authenticated) node-API caller.
  22. maxDecodeBytes = 16 << 20
  23. )
  24. // EncodeAll/DecodeAll on these shared instances are safe for concurrent use.
  25. var (
  26. zstdEncoder, _ = zstd.NewWriter(nil)
  27. zstdDecoder, _ = zstd.NewReader(nil, zstd.WithDecoderMaxMemory(maxDecodeBytes))
  28. )
  29. // Compress zstd-compresses b.
  30. func Compress(b []byte) []byte {
  31. return zstdEncoder.EncodeAll(b, nil)
  32. }
  33. // Decompress zstd-decompresses src, rejecting output larger than maxOut (and any
  34. // input that would blow the in-memory bomb ceiling).
  35. func Decompress(src []byte, maxOut int) ([]byte, error) {
  36. out, err := zstdDecoder.DecodeAll(src, nil)
  37. if err != nil {
  38. return nil, err
  39. }
  40. if maxOut > 0 && len(out) > maxOut {
  41. return nil, errors.New("wirecodec: decompressed body exceeds limit")
  42. }
  43. return out, nil
  44. }
  45. // Sha256Hex returns the lowercase-hex SHA-256 of b.
  46. func Sha256Hex(b []byte) string {
  47. sum := sha256.Sum256(b)
  48. return hex.EncodeToString(sum[:])
  49. }