Documentation
¶
Index ¶
- Constants
- Variables
- func MarshalPayloadHeaderTo(requestID RequestID, payload []byte) error
- type DatagramConn
- type DatagramICMPWriter
- type DatagramType
- type DatagramUDPWriter
- type DroppedReason
- 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") //nolint:errname
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 DroppedReason ¶
type DroppedReason int
const ( DroppedWriteFailed DroppedReason = iota DroppedWriteDeadlineExceeded DroppedWriteFull DroppedWriteFlowUnknown DroppedReadFailed // Origin payloads that are too large to proxy. DroppedReadTooLarge )
func (DroppedReason) String ¶
func (dr DroppedReason) String() string
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(connIndex uint8)
DecrementFlows(connIndex uint8)
FailedFlow(connIndex uint8)
RetryFlowResponse(connIndex uint8)
MigrateFlow(connIndex uint8)
UnsupportedRemoteCommand(connIndex uint8, command string)
DroppedUDPDatagram(connIndex uint8, reason DroppedReason)
DroppedICMPPackets(connIndex uint8, reason DroppedReason)
}
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.Closer
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
Write(payload []byte)
}
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 ¶
func NewSessionManager(metrics Metrics, log *zerolog.Logger, originDialer ingress.OriginUDPDialer, limiter cfdflow.Limiter) SessionManager
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