snapshot: sagernet/gvisor v0.0.0-20250811.0-sing-box-mod.1
Содержимое пина, зафиксированного в go.mod sing-box-lx, одним коммитом без истории. Полная история SagerNet/gvisor — 1.45 ГБ и клонируется в каждой CI-джобе; наша дельта — одна вставка в одну функцию, история для неё не нужна. Module path github.com/sagernet/gvisor сохранён намеренно: на него опирается replace-директива суперпроекта. Патч поверх — отдельным коммитом, чтобы дельта читалась одним git show и переносилась на новый пин копированием. SPECS/TASKS/048-GVISOR_HANDSHAKE_NIL_CRASH
This commit is contained in:
commit
2c4ae3b0a4
712 changed files with 185689 additions and 0 deletions
1098
pkg/tcpip/transport/udp/endpoint.go
Normal file
1098
pkg/tcpip/transport/udp/endpoint.go
Normal file
File diff suppressed because it is too large
Load diff
96
pkg/tcpip/transport/udp/endpoint_state.go
Normal file
96
pkg/tcpip/transport/udp/endpoint_state.go
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
// Copyright 2018 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.
|
||||
|
||||
package udp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/gvisor/pkg/log"
|
||||
"github.com/sagernet/gvisor/pkg/tcpip"
|
||||
"github.com/sagernet/gvisor/pkg/tcpip/stack"
|
||||
"github.com/sagernet/gvisor/pkg/tcpip/transport"
|
||||
)
|
||||
|
||||
// saveReceivedAt is invoked by stateify.
|
||||
func (p *udpPacket) saveReceivedAt() int64 {
|
||||
return p.receivedAt.UnixNano()
|
||||
}
|
||||
|
||||
// loadReceivedAt is invoked by stateify.
|
||||
func (p *udpPacket) loadReceivedAt(_ context.Context, nsec int64) {
|
||||
p.receivedAt = time.Unix(0, nsec)
|
||||
}
|
||||
|
||||
// afterLoad is invoked by stateify.
|
||||
func (e *endpoint) afterLoad(ctx context.Context) {
|
||||
if e.stack.IsSaveRestoreEnabled() {
|
||||
e.stack.RegisterRestoredEndpoint(e)
|
||||
} else {
|
||||
stack.RestoreStackFromContext(ctx).RegisterRestoredEndpoint(e)
|
||||
}
|
||||
}
|
||||
|
||||
// beforeSave is invoked by stateify.
|
||||
func (e *endpoint) beforeSave() {
|
||||
e.freeze()
|
||||
e.stack.RegisterResumableEndpoint(e)
|
||||
}
|
||||
|
||||
// Restore implements tcpip.RestoredEndpoint.Restore.
|
||||
func (e *endpoint) Restore(s *stack.Stack) {
|
||||
e.mu.Lock()
|
||||
defer e.mu.Unlock()
|
||||
|
||||
if err := e.net.Resume(s); err != nil {
|
||||
log.Warningf("Closing the UDP endpoint as it cannot be restored, err: %v", err)
|
||||
e.closeLocked()
|
||||
return
|
||||
}
|
||||
|
||||
// Unfreeze the endpoint to handle packets.
|
||||
e.frozen = false
|
||||
if e.stack.IsSaveRestoreEnabled() {
|
||||
e.ops.InitHandler(e, e.stack, tcpip.GetStackSendBufferLimits, tcpip.GetStackReceiveBufferLimits)
|
||||
return
|
||||
}
|
||||
e.stack = s
|
||||
e.ops.InitHandler(e, e.stack, tcpip.GetStackSendBufferLimits, tcpip.GetStackReceiveBufferLimits)
|
||||
|
||||
switch state := e.net.State(); state {
|
||||
case transport.DatagramEndpointStateInitial, transport.DatagramEndpointStateClosed:
|
||||
case transport.DatagramEndpointStateBound, transport.DatagramEndpointStateConnected:
|
||||
// Our saved state had a port, but we don't actually have a
|
||||
// reservation. We need to remove the port from our state, but still
|
||||
// pass it to the reservation machinery.
|
||||
var err tcpip.Error
|
||||
id := e.net.Info().ID
|
||||
id.LocalPort = e.localPort
|
||||
id.RemotePort = e.remotePort
|
||||
id, e.boundBindToDevice, err = e.registerWithStack(e.effectiveNetProtos, id)
|
||||
if err != nil {
|
||||
panic("registering udp endpoint with the stack failed during restore")
|
||||
}
|
||||
e.localPort = id.LocalPort
|
||||
e.remotePort = id.RemotePort
|
||||
default:
|
||||
panic("unhandled state")
|
||||
}
|
||||
}
|
||||
|
||||
// Resume implements tcpip.ResumableEndpoint.Resume.
|
||||
func (e *endpoint) Resume() {
|
||||
e.thaw()
|
||||
}
|
||||
112
pkg/tcpip/transport/udp/forwarder.go
Normal file
112
pkg/tcpip/transport/udp/forwarder.go
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
// Copyright 2019 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.
|
||||
|
||||
package udp
|
||||
|
||||
import (
|
||||
"github.com/sagernet/gvisor/pkg/tcpip"
|
||||
"github.com/sagernet/gvisor/pkg/tcpip/stack"
|
||||
"github.com/sagernet/gvisor/pkg/waiter"
|
||||
)
|
||||
|
||||
// ForwarderHandler handles incoming requests. Returning true marks the
|
||||
// request as handled, returning false marks the request as unhandled.
|
||||
// Stack may send an ICMP port unreachable message for unhandled requests.
|
||||
type ForwarderHandler func(*ForwarderRequest) (handled bool)
|
||||
|
||||
// Forwarder is a session request forwarder, which allows clients to decide
|
||||
// what to do with a session request, for example: ignore it, or process it.
|
||||
//
|
||||
// The canonical way of using it is to pass the Forwarder.HandlePacket function
|
||||
// to stack.SetTransportProtocolHandler.
|
||||
type Forwarder struct {
|
||||
handler ForwarderHandler
|
||||
|
||||
stack *stack.Stack
|
||||
}
|
||||
|
||||
// NewForwarder allocates and initializes a new forwarder.
|
||||
func NewForwarder(s *stack.Stack, handler ForwarderHandler) *Forwarder {
|
||||
return &Forwarder{
|
||||
stack: s,
|
||||
handler: handler,
|
||||
}
|
||||
}
|
||||
|
||||
// HandlePacket handles all packets.
|
||||
//
|
||||
// This function is expected to be passed as an argument to the
|
||||
// stack.SetTransportProtocolHandler function.
|
||||
func (f *Forwarder) HandlePacket(id stack.TransportEndpointID, pkt *stack.PacketBuffer) bool {
|
||||
return f.handler(&ForwarderRequest{
|
||||
stack: f.stack,
|
||||
id: id,
|
||||
pkt: pkt.Clone(),
|
||||
})
|
||||
}
|
||||
|
||||
// ForwarderRequest represents a session request received by the forwarder and
|
||||
// passed to the client. Clients may optionally create an endpoint to represent
|
||||
// it via CreateEndpoint.
|
||||
type ForwarderRequest struct {
|
||||
stack *stack.Stack
|
||||
id stack.TransportEndpointID
|
||||
pkt *stack.PacketBuffer
|
||||
}
|
||||
|
||||
// ID returns the 4-tuple (src address, src port, dst address, dst port) that
|
||||
// represents the session request.
|
||||
func (r *ForwarderRequest) ID() stack.TransportEndpointID {
|
||||
return r.id
|
||||
}
|
||||
|
||||
// CreateEndpoint creates a connected UDP endpoint for the session request.
|
||||
func (r *ForwarderRequest) CreateEndpoint(queue *waiter.Queue) (tcpip.Endpoint, tcpip.Error) {
|
||||
ep := newEndpoint(r.stack, r.pkt.NetworkProtocolNumber, queue)
|
||||
ep.mu.Lock()
|
||||
defer ep.mu.Unlock()
|
||||
|
||||
netHdr := r.pkt.Network()
|
||||
if err := ep.net.Bind(tcpip.FullAddress{NIC: r.pkt.NICID, Addr: netHdr.DestinationAddress(), Port: r.id.LocalPort}); err != nil {
|
||||
ep.closeLocked()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := ep.net.Connect(tcpip.FullAddress{NIC: r.pkt.NICID, Addr: netHdr.SourceAddress(), Port: r.id.RemotePort}); err != nil {
|
||||
ep.closeLocked()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := r.stack.RegisterTransportEndpoint([]tcpip.NetworkProtocolNumber{r.pkt.NetworkProtocolNumber}, ProtocolNumber, r.id, ep, ep.portFlags, tcpip.NICID(ep.ops.GetBindToDevice())); err != nil {
|
||||
ep.closeLocked()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ep.localPort = r.id.LocalPort
|
||||
ep.remotePort = r.id.RemotePort
|
||||
ep.effectiveNetProtos = []tcpip.NetworkProtocolNumber{r.pkt.NetworkProtocolNumber}
|
||||
ep.boundPortFlags = ep.portFlags
|
||||
|
||||
ep.rcvMu.Lock()
|
||||
ep.rcvReady = true
|
||||
ep.rcvMu.Unlock()
|
||||
|
||||
ep.HandlePacket(r.id, r.pkt)
|
||||
|
||||
return ep, nil
|
||||
}
|
||||
|
||||
func (r *ForwarderRequest) Packet() *stack.PacketBuffer {
|
||||
return r.pkt
|
||||
}
|
||||
138
pkg/tcpip/transport/udp/protocol.go
Normal file
138
pkg/tcpip/transport/udp/protocol.go
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
// Copyright 2018 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.
|
||||
|
||||
// Package udp contains the implementation of the UDP transport protocol.
|
||||
package udp
|
||||
|
||||
import (
|
||||
"github.com/sagernet/gvisor/pkg/tcpip"
|
||||
"github.com/sagernet/gvisor/pkg/tcpip/header"
|
||||
"github.com/sagernet/gvisor/pkg/tcpip/header/parse"
|
||||
"github.com/sagernet/gvisor/pkg/tcpip/stack"
|
||||
"github.com/sagernet/gvisor/pkg/tcpip/transport/raw"
|
||||
"github.com/sagernet/gvisor/pkg/waiter"
|
||||
)
|
||||
|
||||
const (
|
||||
// ProtocolNumber is the udp protocol number.
|
||||
ProtocolNumber = header.UDPProtocolNumber
|
||||
|
||||
// MinBufferSize is the smallest size of a receive or send buffer.
|
||||
MinBufferSize = 4 << 10 // 4KiB bytes.
|
||||
|
||||
// DefaultSendBufferSize is the default size of the send buffer for
|
||||
// an endpoint.
|
||||
DefaultSendBufferSize = 32 << 10 // 32KiB
|
||||
|
||||
// DefaultReceiveBufferSize is the default size of the receive buffer
|
||||
// for an endpoint.
|
||||
DefaultReceiveBufferSize = 32 << 10 // 32KiB
|
||||
|
||||
// MaxBufferSize is the largest size a receive/send buffer can grow to.
|
||||
MaxBufferSize = 4 << 20 // 4MiB
|
||||
)
|
||||
|
||||
// +stateify savable
|
||||
type protocol struct {
|
||||
stack *stack.Stack
|
||||
}
|
||||
|
||||
// Number returns the udp protocol number.
|
||||
func (*protocol) Number() tcpip.TransportProtocolNumber {
|
||||
return ProtocolNumber
|
||||
}
|
||||
|
||||
// NewEndpoint creates a new udp endpoint.
|
||||
func (p *protocol) NewEndpoint(netProto tcpip.NetworkProtocolNumber, waiterQueue *waiter.Queue) (tcpip.Endpoint, tcpip.Error) {
|
||||
return newEndpoint(p.stack, netProto, waiterQueue), nil
|
||||
}
|
||||
|
||||
// NewRawEndpoint creates a new raw UDP endpoint. It implements
|
||||
// stack.TransportProtocol.NewRawEndpoint.
|
||||
func (p *protocol) NewRawEndpoint(netProto tcpip.NetworkProtocolNumber, waiterQueue *waiter.Queue) (tcpip.Endpoint, tcpip.Error) {
|
||||
return raw.NewEndpoint(p.stack, netProto, header.UDPProtocolNumber, waiterQueue)
|
||||
}
|
||||
|
||||
// MinimumPacketSize returns the minimum valid udp packet size.
|
||||
func (*protocol) MinimumPacketSize() int {
|
||||
return header.UDPMinimumSize
|
||||
}
|
||||
|
||||
// ParsePorts returns the source and destination ports stored in the given udp
|
||||
// packet.
|
||||
func (*protocol) ParsePorts(v []byte) (src, dst uint16, err tcpip.Error) {
|
||||
h := header.UDP(v)
|
||||
return h.SourcePort(), h.DestinationPort(), nil
|
||||
}
|
||||
|
||||
// HandleUnknownDestinationPacket handles packets that are targeted at this
|
||||
// protocol but don't match any existing endpoint.
|
||||
func (p *protocol) HandleUnknownDestinationPacket(id stack.TransportEndpointID, pkt *stack.PacketBuffer) stack.UnknownDestinationPacketDisposition {
|
||||
hdr := header.UDP(pkt.TransportHeader().Slice())
|
||||
netHdr := pkt.Network()
|
||||
lengthValid, csumValid := header.UDPValid(
|
||||
hdr,
|
||||
func() uint16 { return pkt.Data().Checksum() },
|
||||
uint16(pkt.Data().Size()),
|
||||
pkt.NetworkProtocolNumber,
|
||||
netHdr.SourceAddress(),
|
||||
netHdr.DestinationAddress(),
|
||||
pkt.RXChecksumValidated)
|
||||
if !lengthValid {
|
||||
p.stack.Stats().UDP.MalformedPacketsReceived.Increment()
|
||||
return stack.UnknownDestinationPacketMalformed
|
||||
}
|
||||
|
||||
if !csumValid {
|
||||
p.stack.Stats().UDP.ChecksumErrors.Increment()
|
||||
return stack.UnknownDestinationPacketMalformed
|
||||
}
|
||||
|
||||
return stack.UnknownDestinationPacketUnhandled
|
||||
}
|
||||
|
||||
// SetOption implements stack.TransportProtocol.SetOption.
|
||||
func (*protocol) SetOption(tcpip.SettableTransportProtocolOption) tcpip.Error {
|
||||
return &tcpip.ErrUnknownProtocolOption{}
|
||||
}
|
||||
|
||||
// Option implements stack.TransportProtocol.Option.
|
||||
func (*protocol) Option(tcpip.GettableTransportProtocolOption) tcpip.Error {
|
||||
return &tcpip.ErrUnknownProtocolOption{}
|
||||
}
|
||||
|
||||
// Close implements stack.TransportProtocol.Close.
|
||||
func (*protocol) Close() {}
|
||||
|
||||
// Wait implements stack.TransportProtocol.Wait.
|
||||
func (*protocol) Wait() {}
|
||||
|
||||
// Pause implements stack.TransportProtocol.Pause.
|
||||
func (*protocol) Pause() {}
|
||||
|
||||
// Resume implements stack.TransportProtocol.Resume.
|
||||
func (*protocol) Resume() {}
|
||||
|
||||
// Restore implements stack.TransportProtocol.Restore.
|
||||
func (*protocol) Restore() {}
|
||||
|
||||
// Parse implements stack.TransportProtocol.Parse.
|
||||
func (*protocol) Parse(pkt *stack.PacketBuffer) bool {
|
||||
return parse.UDP(pkt)
|
||||
}
|
||||
|
||||
// NewProtocol returns a UDP transport protocol.
|
||||
func NewProtocol(s *stack.Stack) stack.TransportProtocol {
|
||||
return &protocol{stack: s}
|
||||
}
|
||||
239
pkg/tcpip/transport/udp/udp_packet_list.go
Normal file
239
pkg/tcpip/transport/udp/udp_packet_list.go
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
package udp
|
||||
|
||||
// ElementMapper provides an identity mapping by default.
|
||||
//
|
||||
// This can be replaced to provide a struct that maps elements to linker
|
||||
// objects, if they are not the same. An ElementMapper is not typically
|
||||
// required if: Linker is left as is, Element is left as is, or Linker and
|
||||
// Element are the same type.
|
||||
type udpPacketElementMapper struct{}
|
||||
|
||||
// linkerFor maps an Element to a Linker.
|
||||
//
|
||||
// This default implementation should be inlined.
|
||||
//
|
||||
//go:nosplit
|
||||
func (udpPacketElementMapper) linkerFor(elem *udpPacket) *udpPacket { return elem }
|
||||
|
||||
// List is an intrusive list. Entries can be added to or removed from the list
|
||||
// in O(1) time and with no additional memory allocations.
|
||||
//
|
||||
// The zero value for List is an empty list ready to use.
|
||||
//
|
||||
// To iterate over a list (where l is a List):
|
||||
//
|
||||
// for e := l.Front(); e != nil; e = e.Next() {
|
||||
// // do something with e.
|
||||
// }
|
||||
//
|
||||
// +stateify savable
|
||||
type udpPacketList struct {
|
||||
head *udpPacket
|
||||
tail *udpPacket
|
||||
}
|
||||
|
||||
// Reset resets list l to the empty state.
|
||||
func (l *udpPacketList) Reset() {
|
||||
l.head = nil
|
||||
l.tail = nil
|
||||
}
|
||||
|
||||
// Empty returns true iff the list is empty.
|
||||
//
|
||||
//go:nosplit
|
||||
func (l *udpPacketList) Empty() bool {
|
||||
return l.head == nil
|
||||
}
|
||||
|
||||
// Front returns the first element of list l or nil.
|
||||
//
|
||||
//go:nosplit
|
||||
func (l *udpPacketList) Front() *udpPacket {
|
||||
return l.head
|
||||
}
|
||||
|
||||
// Back returns the last element of list l or nil.
|
||||
//
|
||||
//go:nosplit
|
||||
func (l *udpPacketList) Back() *udpPacket {
|
||||
return l.tail
|
||||
}
|
||||
|
||||
// Len returns the number of elements in the list.
|
||||
//
|
||||
// NOTE: This is an O(n) operation.
|
||||
//
|
||||
//go:nosplit
|
||||
func (l *udpPacketList) Len() (count int) {
|
||||
for e := l.Front(); e != nil; e = (udpPacketElementMapper{}.linkerFor(e)).Next() {
|
||||
count++
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
// PushFront inserts the element e at the front of list l.
|
||||
//
|
||||
//go:nosplit
|
||||
func (l *udpPacketList) PushFront(e *udpPacket) {
|
||||
linker := udpPacketElementMapper{}.linkerFor(e)
|
||||
linker.SetNext(l.head)
|
||||
linker.SetPrev(nil)
|
||||
if l.head != nil {
|
||||
udpPacketElementMapper{}.linkerFor(l.head).SetPrev(e)
|
||||
} else {
|
||||
l.tail = e
|
||||
}
|
||||
|
||||
l.head = e
|
||||
}
|
||||
|
||||
// PushFrontList inserts list m at the start of list l, emptying m.
|
||||
//
|
||||
//go:nosplit
|
||||
func (l *udpPacketList) PushFrontList(m *udpPacketList) {
|
||||
if l.head == nil {
|
||||
l.head = m.head
|
||||
l.tail = m.tail
|
||||
} else if m.head != nil {
|
||||
udpPacketElementMapper{}.linkerFor(l.head).SetPrev(m.tail)
|
||||
udpPacketElementMapper{}.linkerFor(m.tail).SetNext(l.head)
|
||||
|
||||
l.head = m.head
|
||||
}
|
||||
m.head = nil
|
||||
m.tail = nil
|
||||
}
|
||||
|
||||
// PushBack inserts the element e at the back of list l.
|
||||
//
|
||||
//go:nosplit
|
||||
func (l *udpPacketList) PushBack(e *udpPacket) {
|
||||
linker := udpPacketElementMapper{}.linkerFor(e)
|
||||
linker.SetNext(nil)
|
||||
linker.SetPrev(l.tail)
|
||||
if l.tail != nil {
|
||||
udpPacketElementMapper{}.linkerFor(l.tail).SetNext(e)
|
||||
} else {
|
||||
l.head = e
|
||||
}
|
||||
|
||||
l.tail = e
|
||||
}
|
||||
|
||||
// PushBackList inserts list m at the end of list l, emptying m.
|
||||
//
|
||||
//go:nosplit
|
||||
func (l *udpPacketList) PushBackList(m *udpPacketList) {
|
||||
if l.head == nil {
|
||||
l.head = m.head
|
||||
l.tail = m.tail
|
||||
} else if m.head != nil {
|
||||
udpPacketElementMapper{}.linkerFor(l.tail).SetNext(m.head)
|
||||
udpPacketElementMapper{}.linkerFor(m.head).SetPrev(l.tail)
|
||||
|
||||
l.tail = m.tail
|
||||
}
|
||||
m.head = nil
|
||||
m.tail = nil
|
||||
}
|
||||
|
||||
// InsertAfter inserts e after b.
|
||||
//
|
||||
//go:nosplit
|
||||
func (l *udpPacketList) InsertAfter(b, e *udpPacket) {
|
||||
bLinker := udpPacketElementMapper{}.linkerFor(b)
|
||||
eLinker := udpPacketElementMapper{}.linkerFor(e)
|
||||
|
||||
a := bLinker.Next()
|
||||
|
||||
eLinker.SetNext(a)
|
||||
eLinker.SetPrev(b)
|
||||
bLinker.SetNext(e)
|
||||
|
||||
if a != nil {
|
||||
udpPacketElementMapper{}.linkerFor(a).SetPrev(e)
|
||||
} else {
|
||||
l.tail = e
|
||||
}
|
||||
}
|
||||
|
||||
// InsertBefore inserts e before a.
|
||||
//
|
||||
//go:nosplit
|
||||
func (l *udpPacketList) InsertBefore(a, e *udpPacket) {
|
||||
aLinker := udpPacketElementMapper{}.linkerFor(a)
|
||||
eLinker := udpPacketElementMapper{}.linkerFor(e)
|
||||
|
||||
b := aLinker.Prev()
|
||||
eLinker.SetNext(a)
|
||||
eLinker.SetPrev(b)
|
||||
aLinker.SetPrev(e)
|
||||
|
||||
if b != nil {
|
||||
udpPacketElementMapper{}.linkerFor(b).SetNext(e)
|
||||
} else {
|
||||
l.head = e
|
||||
}
|
||||
}
|
||||
|
||||
// Remove removes e from l.
|
||||
//
|
||||
//go:nosplit
|
||||
func (l *udpPacketList) Remove(e *udpPacket) {
|
||||
linker := udpPacketElementMapper{}.linkerFor(e)
|
||||
prev := linker.Prev()
|
||||
next := linker.Next()
|
||||
|
||||
if prev != nil {
|
||||
udpPacketElementMapper{}.linkerFor(prev).SetNext(next)
|
||||
} else if l.head == e {
|
||||
l.head = next
|
||||
}
|
||||
|
||||
if next != nil {
|
||||
udpPacketElementMapper{}.linkerFor(next).SetPrev(prev)
|
||||
} else if l.tail == e {
|
||||
l.tail = prev
|
||||
}
|
||||
|
||||
linker.SetNext(nil)
|
||||
linker.SetPrev(nil)
|
||||
}
|
||||
|
||||
// Entry is a default implementation of Linker. Users can add anonymous fields
|
||||
// of this type to their structs to make them automatically implement the
|
||||
// methods needed by List.
|
||||
//
|
||||
// +stateify savable
|
||||
type udpPacketEntry struct {
|
||||
next *udpPacket
|
||||
prev *udpPacket
|
||||
}
|
||||
|
||||
// Next returns the entry that follows e in the list.
|
||||
//
|
||||
//go:nosplit
|
||||
func (e *udpPacketEntry) Next() *udpPacket {
|
||||
return e.next
|
||||
}
|
||||
|
||||
// Prev returns the entry that precedes e in the list.
|
||||
//
|
||||
//go:nosplit
|
||||
func (e *udpPacketEntry) Prev() *udpPacket {
|
||||
return e.prev
|
||||
}
|
||||
|
||||
// SetNext assigns 'entry' as the entry that follows e in the list.
|
||||
//
|
||||
//go:nosplit
|
||||
func (e *udpPacketEntry) SetNext(elem *udpPacket) {
|
||||
e.next = elem
|
||||
}
|
||||
|
||||
// SetPrev assigns 'entry' as the entry that precedes e in the list.
|
||||
//
|
||||
//go:nosplit
|
||||
func (e *udpPacketEntry) SetPrev(elem *udpPacket) {
|
||||
e.prev = elem
|
||||
}
|
||||
225
pkg/tcpip/transport/udp/udp_state_autogen.go
Normal file
225
pkg/tcpip/transport/udp/udp_state_autogen.go
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
// automatically generated by stateify.
|
||||
|
||||
package udp
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/sagernet/gvisor/pkg/state"
|
||||
)
|
||||
|
||||
func (p *udpPacket) StateTypeName() string {
|
||||
return "pkg/tcpip/transport/udp.udpPacket"
|
||||
}
|
||||
|
||||
func (p *udpPacket) StateFields() []string {
|
||||
return []string{
|
||||
"udpPacketEntry",
|
||||
"netProto",
|
||||
"senderAddress",
|
||||
"destinationAddress",
|
||||
"packetInfo",
|
||||
"pkt",
|
||||
"receivedAt",
|
||||
"tosOrTClass",
|
||||
"ttlOrHopLimit",
|
||||
}
|
||||
}
|
||||
|
||||
func (p *udpPacket) beforeSave() {}
|
||||
|
||||
// +checklocksignore
|
||||
func (p *udpPacket) StateSave(stateSinkObject state.Sink) {
|
||||
p.beforeSave()
|
||||
var receivedAtValue int64
|
||||
receivedAtValue = p.saveReceivedAt()
|
||||
stateSinkObject.SaveValue(6, receivedAtValue)
|
||||
stateSinkObject.Save(0, &p.udpPacketEntry)
|
||||
stateSinkObject.Save(1, &p.netProto)
|
||||
stateSinkObject.Save(2, &p.senderAddress)
|
||||
stateSinkObject.Save(3, &p.destinationAddress)
|
||||
stateSinkObject.Save(4, &p.packetInfo)
|
||||
stateSinkObject.Save(5, &p.pkt)
|
||||
stateSinkObject.Save(7, &p.tosOrTClass)
|
||||
stateSinkObject.Save(8, &p.ttlOrHopLimit)
|
||||
}
|
||||
|
||||
func (p *udpPacket) afterLoad(context.Context) {}
|
||||
|
||||
// +checklocksignore
|
||||
func (p *udpPacket) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||
stateSourceObject.Load(0, &p.udpPacketEntry)
|
||||
stateSourceObject.Load(1, &p.netProto)
|
||||
stateSourceObject.Load(2, &p.senderAddress)
|
||||
stateSourceObject.Load(3, &p.destinationAddress)
|
||||
stateSourceObject.Load(4, &p.packetInfo)
|
||||
stateSourceObject.Load(5, &p.pkt)
|
||||
stateSourceObject.Load(7, &p.tosOrTClass)
|
||||
stateSourceObject.Load(8, &p.ttlOrHopLimit)
|
||||
stateSourceObject.LoadValue(6, new(int64), func(y any) { p.loadReceivedAt(ctx, y.(int64)) })
|
||||
}
|
||||
|
||||
func (e *endpoint) StateTypeName() string {
|
||||
return "pkg/tcpip/transport/udp.endpoint"
|
||||
}
|
||||
|
||||
func (e *endpoint) StateFields() []string {
|
||||
return []string{
|
||||
"DefaultSocketOptionsHandler",
|
||||
"stack",
|
||||
"waiterQueue",
|
||||
"net",
|
||||
"stats",
|
||||
"ops",
|
||||
"rcvReady",
|
||||
"rcvList",
|
||||
"rcvBufSize",
|
||||
"rcvClosed",
|
||||
"lastError",
|
||||
"portFlags",
|
||||
"boundBindToDevice",
|
||||
"boundPortFlags",
|
||||
"readShutdown",
|
||||
"effectiveNetProtos",
|
||||
"frozen",
|
||||
"localPort",
|
||||
"remotePort",
|
||||
}
|
||||
}
|
||||
|
||||
// +checklocksignore
|
||||
func (e *endpoint) StateSave(stateSinkObject state.Sink) {
|
||||
e.beforeSave()
|
||||
stateSinkObject.Save(0, &e.DefaultSocketOptionsHandler)
|
||||
stateSinkObject.Save(1, &e.stack)
|
||||
stateSinkObject.Save(2, &e.waiterQueue)
|
||||
stateSinkObject.Save(3, &e.net)
|
||||
stateSinkObject.Save(4, &e.stats)
|
||||
stateSinkObject.Save(5, &e.ops)
|
||||
stateSinkObject.Save(6, &e.rcvReady)
|
||||
stateSinkObject.Save(7, &e.rcvList)
|
||||
stateSinkObject.Save(8, &e.rcvBufSize)
|
||||
stateSinkObject.Save(9, &e.rcvClosed)
|
||||
stateSinkObject.Save(10, &e.lastError)
|
||||
stateSinkObject.Save(11, &e.portFlags)
|
||||
stateSinkObject.Save(12, &e.boundBindToDevice)
|
||||
stateSinkObject.Save(13, &e.boundPortFlags)
|
||||
stateSinkObject.Save(14, &e.readShutdown)
|
||||
stateSinkObject.Save(15, &e.effectiveNetProtos)
|
||||
stateSinkObject.Save(16, &e.frozen)
|
||||
stateSinkObject.Save(17, &e.localPort)
|
||||
stateSinkObject.Save(18, &e.remotePort)
|
||||
}
|
||||
|
||||
// +checklocksignore
|
||||
func (e *endpoint) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||
stateSourceObject.Load(0, &e.DefaultSocketOptionsHandler)
|
||||
stateSourceObject.Load(1, &e.stack)
|
||||
stateSourceObject.Load(2, &e.waiterQueue)
|
||||
stateSourceObject.Load(3, &e.net)
|
||||
stateSourceObject.Load(4, &e.stats)
|
||||
stateSourceObject.Load(5, &e.ops)
|
||||
stateSourceObject.Load(6, &e.rcvReady)
|
||||
stateSourceObject.Load(7, &e.rcvList)
|
||||
stateSourceObject.Load(8, &e.rcvBufSize)
|
||||
stateSourceObject.Load(9, &e.rcvClosed)
|
||||
stateSourceObject.Load(10, &e.lastError)
|
||||
stateSourceObject.Load(11, &e.portFlags)
|
||||
stateSourceObject.Load(12, &e.boundBindToDevice)
|
||||
stateSourceObject.Load(13, &e.boundPortFlags)
|
||||
stateSourceObject.Load(14, &e.readShutdown)
|
||||
stateSourceObject.Load(15, &e.effectiveNetProtos)
|
||||
stateSourceObject.Load(16, &e.frozen)
|
||||
stateSourceObject.Load(17, &e.localPort)
|
||||
stateSourceObject.Load(18, &e.remotePort)
|
||||
stateSourceObject.AfterLoad(func() { e.afterLoad(ctx) })
|
||||
}
|
||||
|
||||
func (p *protocol) StateTypeName() string {
|
||||
return "pkg/tcpip/transport/udp.protocol"
|
||||
}
|
||||
|
||||
func (p *protocol) StateFields() []string {
|
||||
return []string{
|
||||
"stack",
|
||||
}
|
||||
}
|
||||
|
||||
func (p *protocol) beforeSave() {}
|
||||
|
||||
// +checklocksignore
|
||||
func (p *protocol) StateSave(stateSinkObject state.Sink) {
|
||||
p.beforeSave()
|
||||
stateSinkObject.Save(0, &p.stack)
|
||||
}
|
||||
|
||||
func (p *protocol) afterLoad(context.Context) {}
|
||||
|
||||
// +checklocksignore
|
||||
func (p *protocol) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||
stateSourceObject.Load(0, &p.stack)
|
||||
}
|
||||
|
||||
func (l *udpPacketList) StateTypeName() string {
|
||||
return "pkg/tcpip/transport/udp.udpPacketList"
|
||||
}
|
||||
|
||||
func (l *udpPacketList) StateFields() []string {
|
||||
return []string{
|
||||
"head",
|
||||
"tail",
|
||||
}
|
||||
}
|
||||
|
||||
func (l *udpPacketList) beforeSave() {}
|
||||
|
||||
// +checklocksignore
|
||||
func (l *udpPacketList) StateSave(stateSinkObject state.Sink) {
|
||||
l.beforeSave()
|
||||
stateSinkObject.Save(0, &l.head)
|
||||
stateSinkObject.Save(1, &l.tail)
|
||||
}
|
||||
|
||||
func (l *udpPacketList) afterLoad(context.Context) {}
|
||||
|
||||
// +checklocksignore
|
||||
func (l *udpPacketList) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||
stateSourceObject.Load(0, &l.head)
|
||||
stateSourceObject.Load(1, &l.tail)
|
||||
}
|
||||
|
||||
func (e *udpPacketEntry) StateTypeName() string {
|
||||
return "pkg/tcpip/transport/udp.udpPacketEntry"
|
||||
}
|
||||
|
||||
func (e *udpPacketEntry) StateFields() []string {
|
||||
return []string{
|
||||
"next",
|
||||
"prev",
|
||||
}
|
||||
}
|
||||
|
||||
func (e *udpPacketEntry) beforeSave() {}
|
||||
|
||||
// +checklocksignore
|
||||
func (e *udpPacketEntry) StateSave(stateSinkObject state.Sink) {
|
||||
e.beforeSave()
|
||||
stateSinkObject.Save(0, &e.next)
|
||||
stateSinkObject.Save(1, &e.prev)
|
||||
}
|
||||
|
||||
func (e *udpPacketEntry) afterLoad(context.Context) {}
|
||||
|
||||
// +checklocksignore
|
||||
func (e *udpPacketEntry) StateLoad(ctx context.Context, stateSourceObject state.Source) {
|
||||
stateSourceObject.Load(0, &e.next)
|
||||
stateSourceObject.Load(1, &e.prev)
|
||||
}
|
||||
|
||||
func init() {
|
||||
state.Register((*udpPacket)(nil))
|
||||
state.Register((*endpoint)(nil))
|
||||
state.Register((*protocol)(nil))
|
||||
state.Register((*udpPacketList)(nil))
|
||||
state.Register((*udpPacketEntry)(nil))
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue