Documentation
¶
Index ¶
- Constants
- Variables
- func MarshalPayloadHeaderTo(requestID RequestID, payload []byte) error
- type DatagramConn
- type DatagramICMPWriter
- type DatagramType
- type DatagramUDPWriter
- type DialUDP
- type ICMPDatagram
- type Metrics
- type QuicConnection
- type RequestID
- type Session
- type SessionIdleErr
- type SessionManager
- type SessionRegistrationResp
- type UDPSessionPayloadDatagram
- type UDPSessionRegistrationDatagram
- type UDPSessionRegistrationResponseDatagram
Constants ¶
const (
DatagramPayloadHeaderLen = datagramTypeLen + datagramRequestIdLen
)
Variables ¶
var ( ErrInvalidDatagramType error = errors.New("invalid datagram type expected") ErrDatagramHeaderTooSmall error = fmt.Errorf("datagram should have at least %d byte", datagramTypeLen) ErrDatagramPayloadTooLarge error = errors.New("payload length is too large to be bundled in datagram") ErrDatagramPayloadHeaderTooSmall error = errors.New("payload length is too small to fit the datagram header") ErrDatagramPayloadInvalidSize error = errors.New("datagram provided is an invalid size") ErrDatagramResponseMsgInvalidSize error = errors.New("datagram response message is an invalid size") ErrDatagramResponseInvalidSize error = errors.New("datagram response is an invalid size") ErrDatagramResponseMsgTooLargeMaximum error = fmt.Errorf("datagram response error message length exceeds the length of the datagram maximum: %d", maxResponseErrorMessageLen) ErrDatagramResponseMsgTooLargeDatagram error = fmt.Errorf("datagram response error message length exceeds the length of the provided datagram") ErrDatagramICMPPayloadTooLarge error = fmt.Errorf("datagram icmp payload exceeds %d bytes", maxICMPPayloadLen) ErrDatagramICMPPayloadMissing error = errors.New("datagram icmp payload is missing") )
var ( // ErrSessionNotFound indicates that a session has not been registered yet for the request id. ErrSessionNotFound = errors.New("flow not found") // ErrSessionBoundToOtherConn is returned when a registration already exists for a different connection. ErrSessionBoundToOtherConn = errors.New("flow is in use by another connection") // ErrSessionAlreadyRegistered is returned when a registration already exists for this connection. ErrSessionAlreadyRegistered = errors.New("flow is already registered for this connection") // ErrSessionRegistrationRateLimited is returned when a registration fails due to rate limiting on the number of active flows. ErrSessionRegistrationRateLimited = errors.New("flow registration rate limited") )
var ( // ErrInvalidRequestIDLen is returned when the provided request id can not be parsed from the provided byte slice. ErrInvalidRequestIDLen error = errors.New("invalid request id length provided") // ErrInvalidPayloadDestLen is returned when the provided destination byte slice cannot fit the whole request id. ErrInvalidPayloadDestLen error = errors.New("invalid payload size provided") )
var SessionCloseErr error = errors.New("flow was closed directly")
SessionCloseErr indicates that the session's Close method was called.
Functions ¶
func MarshalPayloadHeaderTo ¶
MarshalPayloadHeaderTo provides a way to insert the Session Payload header into an already existing byte slice without having to allocate and copy the payload into the destination.
This method should be used in-place of MarshalBinary which will allocate in-place the required byte array to return.
Types ¶
type DatagramConn ¶
type DatagramConn interface { DatagramUDPWriter DatagramICMPWriter // Serve provides a server interface to process and handle incoming QUIC datagrams and demux their datagram v3 payloads. Serve(context.Context) error // ID indicates connection index identifier ID() uint8 }
DatagramConn is the bridge that multiplexes writes and reads of datagrams for UDP sessions and ICMP packets to a connection.
func NewDatagramConn ¶
func NewDatagramConn(conn QuicConnection, sessionManager SessionManager, icmpRouter ingress.ICMPRouter, index uint8, metrics Metrics, logger *zerolog.Logger) DatagramConn
type DatagramICMPWriter ¶
type DatagramICMPWriter interface { SendICMPPacket(icmp *packet.ICMP) error SendICMPTTLExceed(icmp *packet.ICMP, rawPacket packet.RawPacket) error }
DatagramICMPWriter provides the Muxer interface to create ICMP Datagrams when sending over a connection.
type DatagramType ¶
type DatagramType byte
const ( // UDP Registration UDPSessionRegistrationType DatagramType = 0x0 // UDP Session Payload UDPSessionPayloadType DatagramType = 0x1 // DatagramTypeICMP (supporting both ICMPv4 and ICMPv6) ICMPType DatagramType = 0x2 // UDP Session Registration Response UDPSessionRegistrationResponseType DatagramType = 0x3 )
func ParseDatagramType ¶
func ParseDatagramType(data []byte) (DatagramType, error)
type DatagramUDPWriter ¶
type DatagramUDPWriter interface { SendUDPSessionDatagram(datagram []byte) error SendUDPSessionResponse(id RequestID, resp SessionRegistrationResp) error }
DatagramUDPWriter provides the Muxer interface to create proper UDP Datagrams when sending over a connection.
type ICMPDatagram ¶
type ICMPDatagram struct {
Payload []byte
}
ICMPDatagram is used to propagate ICMPv4 and ICMPv6 payloads.
func (*ICMPDatagram) MarshalBinary ¶
func (d *ICMPDatagram) MarshalBinary() (data []byte, err error)
func (*ICMPDatagram) UnmarshalBinary ¶
func (d *ICMPDatagram) UnmarshalBinary(data []byte) error
type Metrics ¶
type Metrics interface { IncrementFlows() DecrementFlows() PayloadTooLarge() RetryFlowResponse() MigrateFlow() }
func NewMetrics ¶
func NewMetrics(registerer prometheus.Registerer) Metrics
type QuicConnection ¶
type QuicConnection interface { Context() context.Context SendDatagram(payload []byte) error ReceiveDatagram(context.Context) ([]byte, error) }
QuicConnection provides an interface that matches [quic.Connection] for only the datagram operations.
We currently rely on the mutex for the [quic.Connection.SendDatagram] and [quic.Connection.ReceiveDatagram] and do not have any locking for them. If the implementation in quic-go were to ever change, we would need to make sure that we lock properly on these operations.
type RequestID ¶
type RequestID uint128
RequestID is the request-id-v2 identifier, it is used to distinguish between specific flows or sessions proxied from the edge to cloudflared.
func RequestIDFromSlice ¶
RequestIDFromSlice reads a request ID from a byte slice.
func (RequestID) Compare ¶
Compare returns an integer comparing two IPs. The result will be 0 if id == id2, -1 if id < id2, and +1 if id > id2. The definition of "less than" is the same as the RequestID.Less method.
func (RequestID) MarshalBinaryTo ¶
MarshalBinaryTo writes the id to the provided destination byte slice; the byte slice must be of at least size 16.
func (*RequestID) UnmarshalBinary ¶
type Session ¶
type Session interface { io.WriteCloser ID() RequestID ConnectionID() uint8 RemoteAddr() net.Addr LocalAddr() net.Addr ResetIdleTimer() Migrate(eyeball DatagramConn, ctx context.Context, logger *zerolog.Logger) // Serve starts the event loop for processing UDP packets Serve(ctx context.Context) error }
type SessionIdleErr ¶
type SessionIdleErr struct {
// contains filtered or unexported fields
}
SessionIdleErr is returned when the session was closed because there was no communication in either direction over the session for the timeout period.
func (SessionIdleErr) Error ¶
func (e SessionIdleErr) Error() string
func (SessionIdleErr) Is ¶
func (e SessionIdleErr) Is(target error) bool
type SessionManager ¶
type SessionManager interface { // RegisterSession will register a new session if it does not already exist for the request ID. // During new session creation, the session will also bind the UDP socket for the origin. // If the session exists for a different connection, it will return [ErrSessionBoundToOtherConn]. RegisterSession(request *UDPSessionRegistrationDatagram, conn DatagramConn) (Session, error) // GetSession returns an active session if available for the provided connection. // If the session does not exist, it will return [ErrSessionNotFound]. If the session exists for a different // connection, it will return [ErrSessionBoundToOtherConn]. GetSession(requestID RequestID) (Session, error) // UnregisterSession will remove a session from the current session manager. It will attempt to close the session // before removal. UnregisterSession(requestID RequestID) }
func NewSessionManager ¶
type SessionRegistrationResp ¶
type SessionRegistrationResp byte
SessionRegistrationResp represents all of the responses that a UDP session registration response can return back to the client.
const ( // Session was received and is ready to proxy. ResponseOk SessionRegistrationResp = 0x00 // Session registration was unable to reach the requested origin destination. ResponseDestinationUnreachable SessionRegistrationResp = 0x01 // Session registration was unable to bind to a local UDP socket. ResponseUnableToBindSocket SessionRegistrationResp = 0x02 // Session registration failed due to the number of flows being higher than the limit. ResponseTooManyActiveFlows SessionRegistrationResp = 0x03 // Session registration failed with an unexpected error but provided a message. ResponseErrorWithMsg SessionRegistrationResp = 0xff )
type UDPSessionPayloadDatagram ¶
UDPSessionPayloadDatagram provides the payload for a session to be send to either the origin or the client.
func (*UDPSessionPayloadDatagram) UnmarshalBinary ¶
func (s *UDPSessionPayloadDatagram) UnmarshalBinary(data []byte) error
type UDPSessionRegistrationDatagram ¶
type UDPSessionRegistrationDatagram struct { RequestID RequestID Dest netip.AddrPort Traced bool IdleDurationHint time.Duration Payload []byte }
UDPSessionRegistrationDatagram handles a request to initialize a UDP session on the remote client.
func (*UDPSessionRegistrationDatagram) MarshalBinary ¶
func (s *UDPSessionRegistrationDatagram) MarshalBinary() (data []byte, err error)
func (*UDPSessionRegistrationDatagram) UnmarshalBinary ¶
func (s *UDPSessionRegistrationDatagram) UnmarshalBinary(data []byte) error
type UDPSessionRegistrationResponseDatagram ¶
type UDPSessionRegistrationResponseDatagram struct { RequestID RequestID ResponseType SessionRegistrationResp ErrorMsg string }
UDPSessionRegistrationResponseDatagram is used to either return a successful registration or error to the client that requested the registration of a UDP session.
func (*UDPSessionRegistrationResponseDatagram) MarshalBinary ¶
func (s *UDPSessionRegistrationResponseDatagram) MarshalBinary() (data []byte, err error)
func (*UDPSessionRegistrationResponseDatagram) UnmarshalBinary ¶
func (s *UDPSessionRegistrationResponseDatagram) UnmarshalBinary(data []byte) error