Files
zeekayandHanzo Dev 3da05638df State the ZAP wire of every urpc payload
urpc encodes with encoding/json, which walks the payload on every call: a
realistic control.ExecArgs costs 7084ns and 10 allocations to cross. ZAP
reads a field at a constant offset out of the buffer that arrived, so the
same payload is 740ns and one allocation -- but only if the offsets are
stated, and a stated offset that is wrong is silent corruption rather than
a compile error. So state them from the types themselves.

//tools/zap reflects over the payloads at build time and writes the wire
as Go source with the offsets as constants. It lives inside Bazel because
pkg/sentry/control cannot be imported from outside it: the *_go_proto
packages it depends on have no source in the tree.

Six payloads had no layout to state. A map, an interface and a type from
another module have no offsets, so each is answered in the type:

  SaveOpts.Metadata and StartContainerArgs.InitialCgroups/Limits cross as
  lists of pairs; boot.Route.Destination restates net.IPNet as Subnet;
  OpenMountArgs restates the OCI mount fields the call actually uses;
  StartArgs.Spec and SinkConfig.Config carry their documents as the bytes
  they arrived as; MetricsRegistrationResponse carries the protocol
  buffer the same way; and seccheck's session options become a type
  instead of a map of any.

ExecArgs and MetricsExportData still have none: ExecArgs holds live
kernel objects behind an interface, and MetricsExportData reaches a
prometheus snapshot whose labels are a map.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-22 23:10:33 -07:00

366 lines
9.4 KiB
Go

// Copyright 2026 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Code generated by zip; DO NOT EDIT.
package seccheck
import (
"encoding/binary"
"encoding/json"
"fmt"
"strings"
zap "github.com/zap-proto/go"
fd "gvisor.dev/gvisor/pkg/fd"
)
// ---- Options -----------------------------------------------------------
const (
optionsExecveHashCacheCapacityAt = 0
optionsSize = 8
)
var _ interface {
MarshalZAP() ([]byte, error)
UnmarshalZAP([]byte) error
} = (*Options)(nil)
// MarshalZAP writes Options from constant offsets.
func (x *Options) MarshalZAP() ([]byte, error) {
if x == nil {
return nil, nil
}
b := zap.NewBuilder(optionsSize + 256)
ob := b.StartObject(optionsSize)
ob.SetInt64(optionsExecveHashCacheCapacityAt, int64(x.ExecveHashCacheCapacity))
ob.FinishAsRoot()
return b.Finish(), nil
}
// UnmarshalZAP reads Options out of the buffer that arrived.
func (x *Options) UnmarshalZAP(data []byte) error {
if x == nil || len(data) == 0 {
return nil
}
m, err := zap.Parse(data)
if err != nil {
return fmt.Errorf("Options: %w", err)
}
o := m.Root()
x.ExecveHashCacheCapacity = int(o.Int64(optionsExecveHashCacheCapacityAt))
return nil
}
// ---- PointConfig -------------------------------------------------------
const (
pointConfigNameAt = 0
pointConfigOptionalFieldsAt = 8
pointConfigContextFieldsAt = 16
pointConfigSize = 24
)
var _ interface {
MarshalZAP() ([]byte, error)
UnmarshalZAP([]byte) error
} = (*PointConfig)(nil)
// MarshalZAP writes PointConfig from constant offsets.
func (x *PointConfig) MarshalZAP() ([]byte, error) {
if x == nil {
return nil, nil
}
b := zap.NewBuilder(pointConfigSize + 256)
optionalFieldsAt, optionalFieldsN := 0, len(x.OptionalFields)
if optionalFieldsN > 0 {
var blob []byte
for i := range x.OptionalFields {
enc := []byte(x.OptionalFields[i])
var n [4]byte
binary.LittleEndian.PutUint32(n[:], uint32(len(enc)))
blob = append(blob, n[:]...)
blob = append(blob, enc...)
}
optionalFieldsAt = b.WriteBytes(blob)
}
contextFieldsAt, contextFieldsN := 0, len(x.ContextFields)
if contextFieldsN > 0 {
var blob []byte
for i := range x.ContextFields {
enc := []byte(x.ContextFields[i])
var n [4]byte
binary.LittleEndian.PutUint32(n[:], uint32(len(enc)))
blob = append(blob, n[:]...)
blob = append(blob, enc...)
}
contextFieldsAt = b.WriteBytes(blob)
}
ob := b.StartObject(pointConfigSize)
ob.SetText(pointConfigNameAt, string(x.Name))
if optionalFieldsN > 0 {
ob.SetList(pointConfigOptionalFieldsAt, optionalFieldsAt, optionalFieldsN)
}
if contextFieldsN > 0 {
ob.SetList(pointConfigContextFieldsAt, contextFieldsAt, contextFieldsN)
}
ob.FinishAsRoot()
return b.Finish(), nil
}
// UnmarshalZAP reads PointConfig out of the buffer that arrived.
func (x *PointConfig) UnmarshalZAP(data []byte) error {
if x == nil || len(data) == 0 {
return nil
}
m, err := zap.Parse(data)
if err != nil {
return fmt.Errorf("PointConfig: %w", err)
}
o := m.Root()
x.Name = string(strings.Clone(o.Text(pointConfigNameAt)))
if l := o.List(pointConfigOptionalFieldsAt); l.Len() > 0 {
rows := make([]string, l.Len())
for i := range rows {
rows[i] = string(l.BytesAt(i))
}
x.OptionalFields = rows
}
if l := o.List(pointConfigContextFieldsAt); l.Len() > 0 {
rows := make([]string, l.Len())
for i := range rows {
rows[i] = string(l.BytesAt(i))
}
x.ContextFields = rows
}
return nil
}
// ---- SessionConfig -----------------------------------------------------
const (
sessionConfigNameAt = 0
sessionConfigPointsAt = 8
sessionConfigIgnoreMissingAt = 16
sessionConfigSinksAt = 24
sessionConfigOptionsAt = 32
sessionConfigSize = 40
)
var _ interface {
MarshalZAP() ([]byte, error)
UnmarshalZAP([]byte) error
} = (*SessionConfig)(nil)
// MarshalZAP writes SessionConfig from constant offsets.
func (x *SessionConfig) MarshalZAP() ([]byte, error) {
if x == nil {
return nil, nil
}
b := zap.NewBuilder(sessionConfigSize + 256)
pointsAt, pointsN := 0, len(x.Points)
if pointsN > 0 {
var blob []byte
for i := range x.Points {
enc, err := x.Points[i].MarshalZAP()
if err != nil {
return nil, err
}
var n [4]byte
binary.LittleEndian.PutUint32(n[:], uint32(len(enc)))
blob = append(blob, n[:]...)
blob = append(blob, enc...)
}
pointsAt = b.WriteBytes(blob)
}
sinksAt, sinksN := 0, len(x.Sinks)
if sinksN > 0 {
var blob []byte
for i := range x.Sinks {
enc, err := x.Sinks[i].MarshalZAP()
if err != nil {
return nil, err
}
var n [4]byte
binary.LittleEndian.PutUint32(n[:], uint32(len(enc)))
blob = append(blob, n[:]...)
blob = append(blob, enc...)
}
sinksAt = b.WriteBytes(blob)
}
ob := b.StartObject(sessionConfigSize)
ob.SetText(sessionConfigNameAt, string(x.Name))
ob.SetBool(sessionConfigIgnoreMissingAt, bool(x.IgnoreMissing))
innerOptions, err := x.Options.MarshalZAP()
if err != nil {
return nil, err
}
ob.SetBytes(sessionConfigOptionsAt, innerOptions)
if pointsN > 0 {
ob.SetList(sessionConfigPointsAt, pointsAt, pointsN)
}
if sinksN > 0 {
ob.SetList(sessionConfigSinksAt, sinksAt, sinksN)
}
ob.FinishAsRoot()
return b.Finish(), nil
}
// UnmarshalZAP reads SessionConfig out of the buffer that arrived.
func (x *SessionConfig) UnmarshalZAP(data []byte) error {
if x == nil || len(data) == 0 {
return nil
}
m, err := zap.Parse(data)
if err != nil {
return fmt.Errorf("SessionConfig: %w", err)
}
o := m.Root()
x.Name = string(strings.Clone(o.Text(sessionConfigNameAt)))
if l := o.List(sessionConfigPointsAt); l.Len() > 0 {
rows := make([]PointConfig, l.Len())
for i := range rows {
if err := rows[i].UnmarshalZAP(l.BytesAt(i)); err != nil {
return err
}
}
x.Points = rows
}
x.IgnoreMissing = bool(o.Bool(sessionConfigIgnoreMissingAt))
if l := o.List(sessionConfigSinksAt); l.Len() > 0 {
rows := make([]SinkConfig, l.Len())
for i := range rows {
if err := rows[i].UnmarshalZAP(l.BytesAt(i)); err != nil {
return err
}
}
x.Sinks = rows
}
if raw := o.Bytes(sessionConfigOptionsAt); len(raw) > 0 {
if err := x.Options.UnmarshalZAP(raw); err != nil {
return err
}
}
return nil
}
// ---- SinkConfig --------------------------------------------------------
const (
sinkConfigNameAt = 0
sinkConfigConfigAt = 8
sinkConfigIgnoreSetupErrorAt = 16
sinkConfigStatusAt = 24
sinkConfigFDAt = 32
sinkConfigSize = 40
)
var _ interface {
MarshalZAP() ([]byte, error)
UnmarshalZAP([]byte) error
} = (*SinkConfig)(nil)
// MarshalZAP writes SinkConfig from constant offsets.
func (x *SinkConfig) MarshalZAP() ([]byte, error) {
if x == nil {
return nil, nil
}
b := zap.NewBuilder(sinkConfigSize + 256)
ob := b.StartObject(sinkConfigSize)
ob.SetText(sinkConfigNameAt, string(x.Name))
ob.SetBytes(sinkConfigConfigAt, []byte(x.Config))
ob.SetBool(sinkConfigIgnoreSetupErrorAt, bool(x.IgnoreSetupError))
innerStatus, err := x.Status.MarshalZAP()
if err != nil {
return nil, err
}
ob.SetBytes(sinkConfigStatusAt, innerStatus)
if x.FD != nil {
innerFD, err := x.FD.MarshalZAP()
if err != nil {
return nil, err
}
ob.SetBytes(sinkConfigFDAt, innerFD)
}
ob.FinishAsRoot()
return b.Finish(), nil
}
// UnmarshalZAP reads SinkConfig out of the buffer that arrived.
func (x *SinkConfig) UnmarshalZAP(data []byte) error {
if x == nil || len(data) == 0 {
return nil
}
m, err := zap.Parse(data)
if err != nil {
return fmt.Errorf("SinkConfig: %w", err)
}
o := m.Root()
x.Name = string(strings.Clone(o.Text(sinkConfigNameAt)))
x.Config = json.RawMessage(append([]byte(nil), o.Bytes(sinkConfigConfigAt)...))
x.IgnoreSetupError = bool(o.Bool(sinkConfigIgnoreSetupErrorAt))
if raw := o.Bytes(sinkConfigStatusAt); len(raw) > 0 {
if err := x.Status.UnmarshalZAP(raw); err != nil {
return err
}
}
if raw := o.Bytes(sinkConfigFDAt); len(raw) > 0 {
var v fd.FD
if err := v.UnmarshalZAP(raw); err != nil {
return err
}
x.FD = &v
}
return nil
}
// ---- SinkStatus --------------------------------------------------------
const (
sinkStatusDroppedCountAt = 0
sinkStatusSize = 8
)
var _ interface {
MarshalZAP() ([]byte, error)
UnmarshalZAP([]byte) error
} = (*SinkStatus)(nil)
// MarshalZAP writes SinkStatus from constant offsets.
func (x *SinkStatus) MarshalZAP() ([]byte, error) {
if x == nil {
return nil, nil
}
b := zap.NewBuilder(sinkStatusSize + 256)
ob := b.StartObject(sinkStatusSize)
ob.SetUint64(sinkStatusDroppedCountAt, uint64(x.DroppedCount))
ob.FinishAsRoot()
return b.Finish(), nil
}
// UnmarshalZAP reads SinkStatus out of the buffer that arrived.
func (x *SinkStatus) UnmarshalZAP(data []byte) error {
if x == nil || len(data) == 0 {
return nil
}
m, err := zap.Parse(data)
if err != nil {
return fmt.Errorf("SinkStatus: %w", err)
}
o := m.Root()
x.DroppedCount = uint64(o.Uint64(sinkStatusDroppedCountAt))
return nil
}