transport

package
v0.0.0-...-385f433 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 25, 2024 License: Apache-2.0, MIT Imports: 17 Imported by: 36

Documentation

Overview

Package transport contains the implementation of Unix endpoints.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewPair

func NewPair(ctx context.Context, stype linux.SockType, uid uniqueid.Provider) (Endpoint, Endpoint)

NewPair allocates a new pair of connected unix-domain connectionedEndpoints.

Types

type Address

type Address struct {
	Addr string
}

Address is a unix socket address.

+stateify savable

type BoundEndpoint

type BoundEndpoint interface {
	// BidirectionalConnect establishes a bi-directional connection between two
	// unix endpoints in an all-or-nothing manner. If an error occurs during
	// connecting, the state of neither endpoint should be modified.
	//
	// In order for an endpoint to establish such a bidirectional connection
	// with a BoundEndpoint, the endpoint calls the BidirectionalConnect method
	// on the BoundEndpoint and sends a representation of itself (the
	// ConnectingEndpoint) and a callback (returnConnect) to receive the
	// connection information (Receiver and ConnectedEndpoint) upon a
	// successful connect. The callback should only be called on a successful
	// connect.
	//
	// For a connection attempt to be successful, the ConnectingEndpoint must
	// be unconnected and not listening and the BoundEndpoint whose
	// BidirectionalConnect method is being called must be listening.
	//
	// This method will return syserr.ErrConnectionRefused on endpoints with a
	// type that isn't SockStream or SockSeqpacket.
	BidirectionalConnect(ctx context.Context, ep ConnectingEndpoint, returnConnect func(Receiver, ConnectedEndpoint)) *syserr.Error

	// UnidirectionalConnect establishes a write-only connection to a unix
	// endpoint.
	//
	// An endpoint which calls UnidirectionalConnect and supports it itself must
	// not hold its own lock when calling UnidirectionalConnect.
	//
	// This method will return syserr.ErrConnectionRefused on a non-SockDgram
	// endpoint.
	UnidirectionalConnect(ctx context.Context) (ConnectedEndpoint, *syserr.Error)

	// Passcred returns whether or not the SO_PASSCRED socket option is
	// enabled on this end.
	Passcred() bool

	// Release releases any resources held by the BoundEndpoint. It must be
	// called before dropping all references to a BoundEndpoint returned by a
	// function.
	Release(ctx context.Context)
}

A BoundEndpoint is a unix endpoint that can be connected to.

type BoundSocketFD

type BoundSocketFD interface {
	// Close closes the socket FD.
	Close(ctx context.Context)

	// NotificationFD is a host FD that can be used to notify when new clients
	// connect to the socket.
	NotificationFD() int32

	// Listen is analogous to listen(2).
	Listen(ctx context.Context, backlog int32) error

	// Accept is analogous to accept(2).
	Accept(ctx context.Context) (int, error)
}

BoundSocketFD is an interface that wraps a socket FD that was bind(2)-ed. It allows to listen and accept on that socket.

type ConnectedEndpoint

type ConnectedEndpoint interface {
	// Passcred implements Endpoint.Passcred.
	Passcred() bool

	// GetLocalAddress implements Endpoint.GetLocalAddress.
	GetLocalAddress() (Address, tcpip.Error)

	// Send sends a single message. This method does not block.
	//
	// notify indicates if SendNotify should be called.
	//
	// syserr.ErrWouldBlock can be returned along with a partial write if
	// the caller should block to send the rest of the data.
	Send(ctx context.Context, data [][]byte, c ControlMessages, from Address) (n int64, notify bool, err *syserr.Error)

	// SendNotify notifies the ConnectedEndpoint of a successful Send. This
	// must not be called while holding any endpoint locks.
	SendNotify()

	// CloseSend prevents the sending of additional Messages.
	//
	// After CloseSend is call, CloseNotify must also be called.
	CloseSend()

	// CloseNotify notifies the ConnectedEndpoint of send being closed. This
	// must not be called while holding any endpoint locks.
	CloseNotify()

	// IsSendClosed returns true if transmission of additional messages is closed.
	IsSendClosed() bool

	// Writable returns if messages should be attempted to be sent. This
	// includes when write has been shutdown.
	Writable() bool

	// EventUpdate lets the ConnectedEndpoint know that event registrations
	// have changed.
	EventUpdate() error

	// SendQueuedSize returns the total amount of data currently queued for
	// sending. SendQueuedSize should return -1 if the operation isn't
	// supported.
	SendQueuedSize() int64

	// SendMaxQueueSize returns maximum value for SendQueuedSize.
	// SendMaxQueueSize should return -1 if the operation isn't supported.
	SendMaxQueueSize() int64

	// Release releases any resources owned by the ConnectedEndpoint. It should
	// be called before dropping all references to a ConnectedEndpoint.
	Release(ctx context.Context)

	// CloseUnread sets the fact that this end is closed with unread data to
	// the peer socket.
	CloseUnread()

	// SetSendBufferSize is called when the endpoint's send buffer size is
	// changed.
	SetSendBufferSize(v int64) (newSz int64)
}

A ConnectedEndpoint is an Endpoint that can be used to send Messages.

type ConnectingEndpoint

type ConnectingEndpoint interface {
	// ID returns the endpoint's globally unique identifier. This identifier
	// must be used to determine locking order if more than one endpoint is
	// to be locked in the same codepath. The endpoint with the smaller
	// identifier must be locked before endpoints with larger identifiers.
	ID() uint64

	// Passcred implements socket.Credentialer.Passcred.
	Passcred() bool

	// Type returns the socket type, typically either SockStream or
	// SockSeqpacket. The connection attempt must be aborted if this
	// value doesn't match the BoundEndpoint's type.
	Type() linux.SockType

	// GetLocalAddress returns the bound path.
	GetLocalAddress() (Address, tcpip.Error)

	// Connected returns true iff the ConnectingEndpoint is in the connected
	// state. ConnectingEndpoints can only be connected to a single endpoint,
	// so the connection attempt must be aborted if this returns true.
	Connected() bool

	// ListeningLocked returns true iff the ConnectingEndpoint is in the
	// listening state. ConnectingEndpoints cannot make connections while
	// listening, so the connection attempt must be aborted if this returns
	// true.
	ListeningLocked() bool

	// WaiterQueue returns a pointer to the endpoint's waiter queue.
	WaiterQueue() *waiter.Queue
	// contains filtered or unexported methods
}

A ConnectingEndpoint is a connectioned unix endpoint that is attempting to establish a bidirectional connection with a BoundEndpoint.

type ControlMessages

type ControlMessages struct {
	// Rights is a control message containing FDs.
	Rights RightsControlMessage

	// Credentials is a control message containing Unix credentials.
	Credentials CredentialsControlMessage
}

A ControlMessages represents a collection of socket control messages.

+stateify savable

func (*ControlMessages) Clone

func (c *ControlMessages) Clone() ControlMessages

Clone clones both the credentials and the rights.

func (*ControlMessages) Empty

func (c *ControlMessages) Empty() bool

Empty returns true iff the ControlMessages does not contain either credentials or rights.

func (*ControlMessages) Release

func (c *ControlMessages) Release(ctx context.Context)

Release releases both the credentials and the rights.

type Credentialer

type Credentialer interface {
	// Passcred returns whether or not the SO_PASSCRED socket option is
	// enabled on this end.
	Passcred() bool

	// ConnectedPasscred returns whether or not the SO_PASSCRED socket option
	// is enabled on the connected end.
	ConnectedPasscred() bool
}

A Credentialer is a socket or endpoint that supports the SO_PASSCRED socket option.

type CredentialsControlMessage

type CredentialsControlMessage interface {
	// Equals returns true iff the two messages are equal.
	Equals(CredentialsControlMessage) bool
}

A CredentialsControlMessage is a control message containing Unix credentials.

type Endpoint

type Endpoint interface {
	Credentialer
	waiter.Waitable

	// Close puts the endpoint in a closed state and frees all resources
	// associated with it.
	Close(ctx context.Context)

	// RecvMsg reads data and a control message from the endpoint. This method
	// does not block if there is no data pending.
	//
	// The returned callback should be called if not nil.
	RecvMsg(ctx context.Context, data [][]byte, args RecvArgs) (RecvOutput, func(), *syserr.Error)

	// SendMsg writes data and a control message to the endpoint's peer.
	// This method does not block if the data cannot be written.
	//
	// SendMsg does not take ownership of any of its arguments on error.
	//
	// If set, notify is a callback that should be called after RecvMesg
	// completes without mm.activeMu held.
	SendMsg(context.Context, [][]byte, ControlMessages, BoundEndpoint) (int64, func(), *syserr.Error)

	// Connect connects this endpoint directly to another.
	//
	// This should be called on the client endpoint, and the (bound)
	// endpoint passed in as a parameter.
	//
	// The error codes are the same as Connect.
	Connect(ctx context.Context, server BoundEndpoint) *syserr.Error

	// Shutdown closes the read and/or write end of the endpoint connection
	// to its peer.
	Shutdown(flags tcpip.ShutdownFlags) *syserr.Error

	// Listen puts the endpoint in "listen" mode, which allows it to accept
	// new connections.
	Listen(ctx context.Context, backlog int) *syserr.Error

	// Accept returns a new endpoint if a peer has established a connection
	// to an endpoint previously set to listen mode. This method does not
	// block if no new connections are available.
	//
	// The returned Queue is the wait queue for the newly created endpoint.
	//
	// peerAddr if not nil will be populated with the address of the connected
	// peer on a successful accept.
	Accept(ctx context.Context, peerAddr *Address) (Endpoint, *syserr.Error)

	// Bind binds the endpoint to a specific local address and port.
	// Specifying a NIC is optional.
	Bind(address Address) *syserr.Error

	// Type return the socket type, typically either SockStream, SockDgram
	// or SockSeqpacket.
	Type() linux.SockType

	// GetLocalAddress returns the address to which the endpoint is bound.
	GetLocalAddress() (Address, tcpip.Error)

	// GetRemoteAddress returns the address to which the endpoint is
	// connected.
	GetRemoteAddress() (Address, tcpip.Error)

	// SetSockOpt sets a socket option.
	SetSockOpt(opt tcpip.SettableSocketOption) tcpip.Error

	// SetSockOptInt sets a socket option for simple cases when a value has
	// the int type.
	SetSockOptInt(opt tcpip.SockOptInt, v int) tcpip.Error

	// GetSockOpt gets a socket option.
	GetSockOpt(opt tcpip.GettableSocketOption) tcpip.Error

	// GetSockOptInt gets a socket option for simple cases when a return
	// value has the int type.
	GetSockOptInt(opt tcpip.SockOptInt) (int, tcpip.Error)

	// State returns the current state of the socket, as represented by Linux in
	// procfs.
	State() uint32

	// LastError clears and returns the last error reported by the endpoint.
	LastError() tcpip.Error

	// SocketOptions returns the structure which contains all the socket
	// level options.
	SocketOptions() *tcpip.SocketOptions
}

Endpoint is the interface implemented by Unix transport protocol implementations that expose functionality like sendmsg, recvmsg, connect, etc. to Unix socket implementations.

func NewConnectioned

func NewConnectioned(ctx context.Context, stype linux.SockType, uid uniqueid.Provider) Endpoint

NewConnectioned creates a new unbound connectionedEndpoint.

func NewConnectionless

func NewConnectionless(ctx context.Context) Endpoint

NewConnectionless creates a new unbound dgram endpoint.

func NewExternal

func NewExternal(stype linux.SockType, uid uniqueid.Provider, queue *waiter.Queue, receiver Receiver, connected ConnectedEndpoint) Endpoint

NewExternal creates a new externally backed Endpoint. It behaves like a socketpair.

type HostBoundEndpoint

type HostBoundEndpoint interface {
	// SetBoundSocketFD will be called on supporting endpoints after
	// binding a socket on the host filesystem. Implementations should
	// delegate Listen and Accept calls to the BoundSocketFD. The ownership
	// of bsFD is transferred to the endpoint.
	SetBoundSocketFD(ctx context.Context, bsFD BoundSocketFD) error

	// ResetBoundSocketFD cleans up the BoundSocketFD set by the last successful
	// SetBoundSocketFD call.
	ResetBoundSocketFD(ctx context.Context)
}

HostBoundEndpoint is an interface that endpoints can implement if they support binding listening and accepting connections from a bound Unix domain socket on the host.

type HostConnectedEndpoint

type HostConnectedEndpoint struct {
	HostConnectedEndpointRefs
	// contains filtered or unexported fields
}

HostConnectedEndpoint is an implementation of ConnectedEndpoint and Receiver. It is backed by a host fd that was imported at sentry startup. This fd is shared with a hostfs inode, which retains ownership of it.

HostConnectedEndpoint is saveable, since we expect that the host will provide the same fd upon restore.

As of this writing, we only allow Unix sockets to be imported.

+stateify savable

func NewHostConnectedEndpoint

func NewHostConnectedEndpoint(hostFD int, addr string) (*HostConnectedEndpoint, *syserr.Error)

NewHostConnectedEndpoint creates a new HostConnectedEndpoint backed by a host fd imported at sentry startup.

The caller is responsible for calling Init(). Additionally, Release needs to be called twice because HostConnectedEndpoint is both a Receiver and HostConnectedEndpoint.

func (*HostConnectedEndpoint) CloseNotify

func (c *HostConnectedEndpoint) CloseNotify()

CloseNotify implements ConnectedEndpoint.CloseNotify.

func (*HostConnectedEndpoint) CloseRecv

func (c *HostConnectedEndpoint) CloseRecv()

CloseRecv implements Receiver.CloseRecv.

func (*HostConnectedEndpoint) CloseSend

func (c *HostConnectedEndpoint) CloseSend()

CloseSend implements ConnectedEndpoint.CloseSend.

func (*HostConnectedEndpoint) CloseUnread

func (c *HostConnectedEndpoint) CloseUnread()

CloseUnread implements ConnectedEndpoint.CloseUnread.

func (*HostConnectedEndpoint) EventUpdate

func (c *HostConnectedEndpoint) EventUpdate() error

EventUpdate implements ConnectedEndpoint.EventUpdate.

func (*HostConnectedEndpoint) GetLocalAddress

func (c *HostConnectedEndpoint) GetLocalAddress() (Address, tcpip.Error)

GetLocalAddress implements ConnectedEndpoint.GetLocalAddress.

func (*HostConnectedEndpoint) IsRecvClosed

func (c *HostConnectedEndpoint) IsRecvClosed() bool

IsRecvClosed implements Receiver.IsRecvClosed.

func (*HostConnectedEndpoint) IsSendClosed

func (c *HostConnectedEndpoint) IsSendClosed() bool

IsSendClosed implements ConnectedEndpoint.IsSendClosed.

func (*HostConnectedEndpoint) Passcred

func (c *HostConnectedEndpoint) Passcred() bool

Passcred implements ConnectedEndpoint.Passcred.

func (*HostConnectedEndpoint) Readable

func (c *HostConnectedEndpoint) Readable() bool

Readable implements Receiver.Readable.

func (*HostConnectedEndpoint) Recv

func (c *HostConnectedEndpoint) Recv(ctx context.Context, data [][]byte, args RecvArgs) (RecvOutput, bool, *syserr.Error)

Recv implements Receiver.Recv.

func (*HostConnectedEndpoint) RecvMaxQueueSize

func (c *HostConnectedEndpoint) RecvMaxQueueSize() int64

RecvMaxQueueSize implements Receiver.RecvMaxQueueSize.

func (*HostConnectedEndpoint) RecvNotify

func (c *HostConnectedEndpoint) RecvNotify()

RecvNotify implements Receiver.RecvNotify.

func (*HostConnectedEndpoint) RecvQueuedSize

func (c *HostConnectedEndpoint) RecvQueuedSize() int64

RecvQueuedSize implements Receiver.RecvQueuedSize.

func (*HostConnectedEndpoint) Release

func (c *HostConnectedEndpoint) Release(ctx context.Context)

Release implements ConnectedEndpoint.Release and Receiver.Release.

func (*HostConnectedEndpoint) Send

func (c *HostConnectedEndpoint) Send(ctx context.Context, data [][]byte, controlMessages ControlMessages, from Address) (int64, bool, *syserr.Error)

Send implements ConnectedEndpoint.Send.

func (*HostConnectedEndpoint) SendMaxQueueSize

func (c *HostConnectedEndpoint) SendMaxQueueSize() int64

SendMaxQueueSize implements Receiver.SendMaxQueueSize.

func (*HostConnectedEndpoint) SendNotify

func (c *HostConnectedEndpoint) SendNotify()

SendNotify implements ConnectedEndpoint.SendNotify.

func (*HostConnectedEndpoint) SendQueuedSize

func (c *HostConnectedEndpoint) SendQueuedSize() int64

SendQueuedSize implements Receiver.SendQueuedSize.

func (*HostConnectedEndpoint) SetReceiveBufferSize

func (c *HostConnectedEndpoint) SetReceiveBufferSize(v int64) (newSz int64)

SetReceiveBufferSize implements ConnectedEndpoint.SetReceiveBufferSize.

func (*HostConnectedEndpoint) SetSendBufferSize

func (c *HostConnectedEndpoint) SetSendBufferSize(v int64) (newSz int64)

SetSendBufferSize implements ConnectedEndpoint.SetSendBufferSize.

func (*HostConnectedEndpoint) SockType

func (c *HostConnectedEndpoint) SockType() linux.SockType

SockType returns the underlying socket type.

func (*HostConnectedEndpoint) Writable

func (c *HostConnectedEndpoint) Writable() bool

Writable implements ConnectedEndpoint.Writable.

type Receiver

type Receiver interface {
	// Recv receives a single message. This method does not block.
	//
	// notify indicates if RecvNotify should be called.
	Recv(ctx context.Context, data [][]byte, args RecvArgs) (out RecvOutput, notify bool, err *syserr.Error)

	// RecvNotify notifies the Receiver of a successful Recv. This must not be
	// called while holding any endpoint locks.
	RecvNotify()

	// CloseRecv prevents the receiving of additional Messages.
	//
	// After CloseRecv is called, CloseNotify must also be called.
	CloseRecv()

	// CloseNotify notifies the Receiver of recv being closed. This must not be
	// called while holding any endpoint locks.
	CloseNotify()

	// IsRecvClosed returns true if reception of additional messages is closed.
	IsRecvClosed() bool

	// Readable returns if messages should be attempted to be received. This
	// includes when read has been shutdown.
	Readable() bool

	// RecvQueuedSize returns the total amount of data currently receivable.
	// RecvQueuedSize should return -1 if the operation isn't supported.
	RecvQueuedSize() int64

	// RecvMaxQueueSize returns maximum value for RecvQueuedSize.
	// RecvMaxQueueSize should return -1 if the operation isn't supported.
	RecvMaxQueueSize() int64

	// Release releases any resources owned by the Receiver. It should be
	// called before dropping all references to a Receiver.
	Release(ctx context.Context)
}

A Receiver can be used to receive Messages.

type RecvArgs

type RecvArgs struct {
	// Creds indicates if credential control messages are requested by the
	// caller. This is useful for determining if control messages can be
	// coalesced. Creds is a hint and can be safely ignored by the
	// implementation if no coalescing is possible. It is fine to return
	// credential control messages when none were requested or to not
	// return credential control messages when they were requested.
	Creds bool

	// NumRights is the number of SCM_RIGHTS FDs requested by the caller.
	// This is useful if one must allocate a buffer to receive a SCM_RIGHTS
	// message or determine if control messages can be coalesced. numRights
	// is a hint and can be safely ignored by the implementation if the
	// number of available SCM_RIGHTS FDs is known and no coalescing is
	// possible. It is fine for the returned number of SCM_RIGHTS FDs to be
	// either higher or lower than the requested number.
	NumRights int

	// If Peek is true, no data should be consumed from the Endpoint. Any and
	// all data returned from a peek should be available in the next call to
	// Recv or RecvMsg.
	Peek bool
}

RecvArgs are the arguments to Endpoint.RecvMsg and Receiver.Recv.

type RecvOutput

type RecvOutput struct {
	// RecvLen is the number of bytes copied into RecvArgs.Data.
	RecvLen int64

	// MsgLen is the length of the read message consumed for datagram Endpoints.
	// MsgLen is always the same as RecvLen for stream Endpoints.
	MsgLen int64

	// Source is the source address we received from.
	Source Address

	// Control is the ControlMessages read.
	Control ControlMessages

	// ControlTrunc indicates that the NumRights hint was used to receive
	// fewer than the total available SCM_RIGHTS FDs. Additional truncation
	// may be required by the caller.
	ControlTrunc bool

	// UnusedRights is a slice of unused RightsControlMessage which should
	// be Release()d.
	UnusedRights []RightsControlMessage
}

RecvOutput is the output from Endpoint.RecvMsg and Receiver.Recv.

type RightsControlMessage

type RightsControlMessage interface {
	// Clone returns a copy of the RightsControlMessage.
	Clone() RightsControlMessage

	// Release releases any resources owned by the RightsControlMessage.
	Release(ctx context.Context)
}

A RightsControlMessage is a control message containing FDs.

+stateify savable

type SCMConnectedEndpoint

type SCMConnectedEndpoint struct {
	HostConnectedEndpoint
	// contains filtered or unexported fields
}

SCMConnectedEndpoint represents an endpoint backed by a host fd that was passed through a gofer Unix socket. It resembles HostConnectedEndpoint, with the following differences:

  • SCMConnectedEndpoint is not saveable, because the host cannot guarantee the same descriptor number across S/R.
  • SCMConnectedEndpoint holds ownership of its fd and notification queue.

func NewSCMEndpoint

func NewSCMEndpoint(hostFD int, queue *waiter.Queue, addr string) (*SCMConnectedEndpoint, *syserr.Error)

NewSCMEndpoint creates a new SCMConnectedEndpoint backed by a host fd that was passed through a Unix socket.

The caller is responsible for calling Init(). Additionally, Release needs to be called twice because ConnectedEndpoint is both a Receiver and ConnectedEndpoint.

func (*SCMConnectedEndpoint) Init

func (e *SCMConnectedEndpoint) Init() error

Init will do the initialization required without holding other locks.

func (*SCMConnectedEndpoint) Release

func (e *SCMConnectedEndpoint) Release(ctx context.Context)

Release implements ConnectedEndpoint.Release and Receiver.Release.

type SCMRights

type SCMRights struct {
	FDs []int
}

SCMRights implements RightsControlMessage with host FDs.

func (*SCMRights) Clone

func (c *SCMRights) Clone() RightsControlMessage

Clone implements RightsControlMessage.Clone.

func (*SCMRights) Release

func (c *SCMRights) Release(ctx context.Context)

Release implements RightsControlMessage.Release.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL