agents

package
v0.0.0-...-434cb5b Latest Latest
Warning

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

Go to latest
Published: Aug 1, 2023 License: AGPL-3.0 Imports: 18 Imported by: 4

Documentation

Overview

This package contains pieces of behaviours that constitutes a QUIC client.

Each agent is responsible for a limited part of the behaviour of a QUIC client. This allows modularity when defining test scenarii with specific needs. Each agent is described in its type documentation. For more information on the architecture of QUIC-Tracker, please consult the package quictracker documentation.

Index

Constants

View Source
const (
	QPACKNoStream           uint64 = math.MaxUint64
	QPACKEncoderStreamValue        = 0x2
	QPACKDecoderStreamValue        = 0x3
)
View Source
const (
	HTTPNoStream uint64 = math.MaxUint64
)

Variables

View Source
var FramePriority = map[FrameType]int{
	ConnectionCloseType:    1,
	ApplicationCloseType:   2,
	PathResponseType:       3,
	AckType:                4,
	AckECNType:             5,
	CryptoType:             6,
	PingType:               7,
	NewConnectionIdType:    8,
	RetireConnectionIdType: 9,
	PathChallengeType:      10,
	ResetStreamType:        11,
	StopSendingType:        12,
	MaxDataType:            13,
	MaxStreamDataType:      14,
	MaxStreamsType:         15,
	MaxStreamsType + 1:     16,
	DataBlockedType:        17,
	StreamDataBlockedType:  18,
	StreamsBlockedType:     19,
	StreamsBlockedType + 1: 20,
	NewTokenType:           21,
	StreamType:             22,
	PaddingFrameType:       23,
}

Functions

This section is empty.

Types

type AckAgent

type AckAgent struct {
	FrameProducingAgent
	DisableAcks         map[PNSpace]bool
	TotalDataAcked      map[PNSpace]uint64
	DisablePathResponse bool
}

The AckAgent is in charge of queuing ACK frames in response to receiving packets that need to be acknowledged as well as answering to PATH_CHALLENGE frames. Both can be disabled independently for a finer control on its behaviour.

func (*AckAgent) Run

func (a *AckAgent) Run(conn *Connection)

type Agent

type Agent interface {
	Name() string
	Init(name string, ODCID ConnectionID)
	Run(conn *Connection)
	Stop()
	Restart()
	Join()
}

func GetDefaultAgents

func GetDefaultAgents() []Agent

Returns the agents needed for a basic QUIC connection to operate

type BaseAgent

type BaseAgent struct {
	Logger *log.Logger
	// contains filtered or unexported fields
}

All agents should embed this structure

func (*BaseAgent) Init

func (a *BaseAgent) Init(name string, ODCID ConnectionID)

All agents that embed this structure must call Init() as soon as their Run() method is called

func (*BaseAgent) Join

func (a *BaseAgent) Join()

func (*BaseAgent) Name

func (a *BaseAgent) Name() string

func (*BaseAgent) Restart

func (a *BaseAgent) Restart()

func (*BaseAgent) Stop

func (a *BaseAgent) Stop()

type BufferAgent

type BufferAgent struct {
	BaseAgent
}

The BufferAgent is in charge of waiting for a given decryption level to become available before putting ciphertexts that require this level back into the decryption queue.

func (*BufferAgent) Run

func (a *BufferAgent) Run(conn *Connection)

type ClosingAgent

type ClosingAgent struct {
	BaseAgent

	IdleDuration time.Duration
	IdleTimeout  *time.Timer
	// contains filtered or unexported fields
}

The ClosingAgent is responsible for keeping track of events that can close the connection, such as the idle timeout. It can queue an (CONNECTION|APPLICATION)_CLOSE frame and wait for it to be sent out.

func (*ClosingAgent) Close

func (a *ClosingAgent) Close(quicLayer bool, errorCode uint64, reasonPhrase string)

func (*ClosingAgent) Run

func (a *ClosingAgent) Run(conn *Connection)

type ConnectionAgents

type ConnectionAgents struct {
	// contains filtered or unexported fields
}

Represents a set of agents that are attached to a particular connection

func AttachAgentsToConnection

func AttachAgentsToConnection(conn *Connection, agents ...Agent) *ConnectionAgents

func (*ConnectionAgents) Add

func (c *ConnectionAgents) Add(agent Agent)

func (*ConnectionAgents) AddHTTPAgent

func (c *ConnectionAgents) AddHTTPAgent() HTTPAgent

func (*ConnectionAgents) CloseConnection

func (c *ConnectionAgents) CloseConnection(quicLayer bool, errorCode uint64, reasonPhrase string)

This function sends an (CONNECTION|APPLICATION)_CLOSE frame and wait for it to be sent out. Then it stops all the agents attached to this connection.

func (*ConnectionAgents) Get

func (c *ConnectionAgents) Get(name string) Agent

func (*ConnectionAgents) GetFrameProducingAgents

func (c *ConnectionAgents) GetFrameProducingAgents() []FrameProducer

func (*ConnectionAgents) Has

func (c *ConnectionAgents) Has(name string) (Agent, bool)

func (*ConnectionAgents) Stop

func (c *ConnectionAgents) Stop(names ...string)

func (*ConnectionAgents) StopAll

func (c *ConnectionAgents) StopAll()

type DecodedHeaders

type DecodedHeaders struct {
	StreamID uint64
	Headers  []HTTPHeader
}

type EncodedHeaders

type EncodedHeaders struct {
	StreamID uint64
	Headers  []byte
}

type FlowControlAgent

type FlowControlAgent struct {
	FrameProducingAgent
	LocalFC               FlowControlLimits
	RemoteFC              FlowControlLimits
	DontSlideCreditWindow bool
	// contains filtered or unexported fields
}

func (*FlowControlAgent) InitStreamLimits

func (a *FlowControlAgent) InitStreamLimits(stream *Stream, streamId uint64)

func (*FlowControlAgent) ReserveAtMost

func (a *FlowControlAgent) ReserveAtMost(streamId uint64, amount uint64) uint64

func (*FlowControlAgent) ReserveCredit

func (a *FlowControlAgent) ReserveCredit(streamId uint64, amount uint64) uint64

func (*FlowControlAgent) Run

func (a *FlowControlAgent) Run(conn *Connection)

type FlowControlLimits

type FlowControlLimits struct {
	StreamsBidi             uint64
	StreamsUni              uint64
	MaxData                 uint64
	MaxStreamDataBidiLocal  uint64
	MaxStreamDataBidiRemote uint64
	MaxStreamDataUni        uint64
}

func (*FlowControlLimits) Copy

func (f *FlowControlLimits) Copy(tp *QuicTransportParameters)

type FramePriorityQueue

type FramePriorityQueue []*item

func NewFramePriorityQueue

func NewFramePriorityQueue() *FramePriorityQueue

func (FramePriorityQueue) Len

func (pq FramePriorityQueue) Len() int

func (FramePriorityQueue) Less

func (pq FramePriorityQueue) Less(i, j int) bool

func (*FramePriorityQueue) Peek

func (pq *FramePriorityQueue) Peek() Frame

func (*FramePriorityQueue) Pop

func (pq *FramePriorityQueue) Pop() interface{}

func (*FramePriorityQueue) Push

func (pq *FramePriorityQueue) Push(x interface{})

func (FramePriorityQueue) Swap

func (pq FramePriorityQueue) Swap(i, j int)

type FrameProducer

type FrameProducer interface {
	RequestFrames(availableSpace int, level EncryptionLevel, number PacketNumber) ([]Frame, bool)
}

type FrameProducingAgent

type FrameProducingAgent struct {
	BaseAgent
	// contains filtered or unexported fields
}

func (*FrameProducingAgent) InitFPA

func (a *FrameProducingAgent) InitFPA(conn *Connection)

func (*FrameProducingAgent) RequestFrames

func (a *FrameProducingAgent) RequestFrames(availableSpace int, level EncryptionLevel, number PacketNumber) ([]Frame, bool)

func (*FrameProducingAgent) Run

func (a *FrameProducingAgent) Run(conn *Connection)

type FrameQueueAgent

type FrameQueueAgent struct {
	FrameProducingAgent
}

func (*FrameQueueAgent) Run

func (a *FrameQueueAgent) Run(conn *Connection)

The FrameQueueAgent collects all the frames that should be packed into packets and order them by frame type priority. Each type of frame is given a level of priority as expressed in FramePriority.

type HTTP09Agent

type HTTP09Agent struct {
	BaseAgent
	// contains filtered or unexported fields
}

func (*HTTP09Agent) HTTPResponseReceived

func (a *HTTP09Agent) HTTPResponseReceived() Broadcaster

func (*HTTP09Agent) Run

func (a *HTTP09Agent) Run(conn *Connection)

func (*HTTP09Agent) SendRequest

func (a *HTTP09Agent) SendRequest(path, method, authority string, headers map[string]string) chan HTTPResponse

type HTTP09Response

type HTTP09Response struct {
	// contains filtered or unexported fields
}

func (*HTTP09Response) Body

func (r *HTTP09Response) Body() []byte

func (*HTTP09Response) Headers

func (r *HTTP09Response) Headers() []HTTPHeader

func (*HTTP09Response) StreamID

func (r *HTTP09Response) StreamID() uint64

type HTTP3Agent

type HTTP3Agent struct {
	BaseAgent

	DisableQPACKStreams bool
	QPACK               QPACKAgent
	QPACKEncoderOpts    uint32

	FrameReceived    Broadcaster //type: HTTP3FrameReceived
	ReceivedSettings *http3.SETTINGS
	// contains filtered or unexported fields
}

The HTTP3 Agent is TODO

func (*HTTP3Agent) HTTPResponseReceived

func (a *HTTP3Agent) HTTPResponseReceived() Broadcaster

func (*HTTP3Agent) Run

func (a *HTTP3Agent) Run(conn *Connection)

func (*HTTP3Agent) SendRequest

func (a *HTTP3Agent) SendRequest(path, method, authority string, headers map[string]string) chan HTTPResponse

type HTTP3FrameReceived

type HTTP3FrameReceived struct {
	StreamID uint64
	Frame    http3.HTTPFrame
}

type HTTP3Response

type HTTP3Response struct {
	HTTP09Response
	// contains filtered or unexported fields
}

func (HTTP3Response) Complete

func (r HTTP3Response) Complete() bool

func (HTTP3Response) Headers

func (r HTTP3Response) Headers() []HTTPHeader

type HTTPAgent

type HTTPAgent interface {
	Agent
	SendRequest(path, method, authority string, headers map[string]string) chan HTTPResponse
	HTTPResponseReceived() Broadcaster
}

type HTTPHeader

type HTTPHeader struct {
	Name, Value string
}

type HTTPResponse

type HTTPResponse interface {
	StreamID() uint64
	Headers() []HTTPHeader
	Body() []byte
}

type HandshakeAgent

type HandshakeAgent struct {
	BaseAgent
	TLSAgent        *TLSAgent
	SocketAgent     *SocketAgent
	HandshakeStatus Broadcaster //type: HandshakeStatus
	IgnoreRetry     bool
	DontDropKeys    bool
	// contains filtered or unexported fields
}

The HandshakeAgent is responsible for initiating the QUIC handshake and respond to the version negotiation process if the server requires it. It reports the status of the handshake through the HandshakeStatus attribute. The status should only be published once, reporting a failure or a success.

func (*HandshakeAgent) InitiateHandshake

func (a *HandshakeAgent) InitiateHandshake()

func (*HandshakeAgent) Run

func (a *HandshakeAgent) Run(conn *Connection)

type HandshakeStatus

type HandshakeStatus struct {
	Completed bool
	Packet
	Error error
}

func (HandshakeStatus) String

func (s HandshakeStatus) String() string

type ParsingAgent

type ParsingAgent struct {
	BaseAgent
	// contains filtered or unexported fields
}

The ParsingAgent is responsible for decrypting and parsing the payloads received in UDP datagrams. It also decrypts the packet number if needed. Payloads that require a decryption level that is not available are put back into the UnprocessedPayloads queue.

func (*ParsingAgent) Run

func (a *ParsingAgent) Run(conn *Connection)

func (*ParsingAgent) SaveCleartextPacket

func (a *ParsingAgent) SaveCleartextPacket(cleartext []byte, unique unsafe.Pointer)

type QLogAgent

type QLogAgent struct {
	BaseAgent
}

func (*QLogAgent) Run

func (a *QLogAgent) Run(conn *Connection)

type QPACKAgent

type QPACKAgent struct {
	BaseAgent
	EncoderStreamID uint64
	DecoderStreamID uint64
	DisableStreams  bool
	DecodeHeaders   chan EncodedHeaders
	DecodedHeaders  Broadcaster //type: DecodedHeaders
	EncodeHeaders   chan DecodedHeaders
	EncodedHeaders  Broadcaster //type: EncodedHeaders
	// contains filtered or unexported fields
}

The QPACK Agent is TODO

func (*QPACKAgent) InitEncoder

func (a *QPACKAgent) InitEncoder(headerTableSize uint, dynamicTablesize uint, maxRiskedStreams uint, opts uint32)

func (*QPACKAgent) Run

func (a *QPACKAgent) Run(conn *Connection)

type RTTAgent

type RTTAgent struct {
	BaseAgent

	MinRTT             uint64
	LatestRTT          uint64
	SmoothedRTT        uint64
	RTTVar             uint64
	MaxAckDelay        uint64
	SentPackets        map[PNSpace]map[PacketNumber]SentPacket
	LargestSentPackets map[PNSpace]PacketNumber
	// contains filtered or unexported fields
}

func (*RTTAgent) Run

func (a *RTTAgent) Run(conn *Connection)

func (*RTTAgent) UpdateRTT

func (a *RTTAgent) UpdateRTT(ackDelay uint64, ackOnly bool)

type RecoveryAgent

type RecoveryAgent struct {
	BaseAgent

	TimerValue time.Duration
	// contains filtered or unexported fields
}

The RecoveryAgent is responsible of retransmitting frames that are part of packets considered as lost. It currently implements a simpler version of the Fast Retransmit mechanism and a linear Retransmission Timeout alarm.

func (*RecoveryAgent) PacketAcknowledged

func (a *RecoveryAgent) PacketAcknowledged(packet PacketNumber, space PNSpace)

func (*RecoveryAgent) ProcessAck

func (a *RecoveryAgent) ProcessAck(ack *AckFrame, space PNSpace) RetransmitBatch

func (*RecoveryAgent) RetransmitBatch

func (a *RecoveryAgent) RetransmitBatch(batch RetransmitBatch)

func (*RecoveryAgent) Run

func (a *RecoveryAgent) Run(conn *Connection)

type RequestFrameArgs

type RequestFrameArgs struct {
	// contains filtered or unexported fields
}

type RetransmitBatch

type RetransmitBatch []RetransmittableFrames

func (RetransmitBatch) Len

func (a RetransmitBatch) Len() int

func (RetransmitBatch) Less

func (a RetransmitBatch) Less(i, j int) bool

func (RetransmitBatch) NFrames

func (a RetransmitBatch) NFrames() int

func (RetransmitBatch) Swap

func (a RetransmitBatch) Swap(i, j int)

type RetransmittableFrames

type RetransmittableFrames struct {
	Frames    []Frame
	Timestamp time.Time
	Level     EncryptionLevel
}

func NewRetransmittableFrames

func NewRetransmittableFrames(frames []Frame, level EncryptionLevel) *RetransmittableFrames

type SendingAgent

type SendingAgent struct {
	BaseAgent
	MTU                         uint16
	FrameProducer               []FrameProducer
	DontCoalesceZeroRTT         bool
	KeepDroppedEncryptionLevels bool
}

The SendingAgent is responsible of bundling frames for sending from other agents into packets. If the frames queued for a given encryption level are smaller than a given MTU, it will wait a window of 5ms before sending them in the hope that more will be queued. Frames that require an unavailable encryption level are queued until it is made available. It also merge the ACK frames inside a given packet before sending.

func (*SendingAgent) Run

func (a *SendingAgent) Run(conn *Connection)

type SentPacket

type SentPacket struct {
	// contains filtered or unexported fields
}

type SocketAgent

type SocketAgent struct {
	BaseAgent

	TotalDataReceived int
	DatagramsReceived int
	SocketStatus      Broadcaster //type: err
	// contains filtered or unexported fields
}

The SocketAgent is responsible for receiving the UDP payloads off the socket and putting them in the decryption queue. If configured using ConfigureECN(), it will also mark the packet as with ECN(0) and report the ECN status of the corresponding IP packet received.

func (*SocketAgent) ConfigureECN

func (a *SocketAgent) ConfigureECN() error

func (*SocketAgent) Run

func (a *SocketAgent) Run(conn *Connection)

type StreamAgent

type StreamAgent struct {
	FrameProducingAgent

	FlowControlAgent *FlowControlAgent
	// contains filtered or unexported fields
}

func (*StreamAgent) Run

func (a *StreamAgent) Run(conn *Connection)

type TLSAgent

type TLSAgent struct {
	BaseAgent
	TLSStatus           Broadcaster //type: TLSStatus
	ResumptionTicket    Broadcaster //type: []byte
	DisableFrameSending bool
}

The TLSAgent is responsible of interacting with the TLS-1.3 stack. It waits on the CRYPTO streams for new data and feed it to the TLS stack. Any response is queued in a corresponding CRYPTO frame, unless disabled using DisableFrameSending. The TLSAgent will broadcast when new encryption or decryption levels are available.

func (*TLSAgent) Run

func (a *TLSAgent) Run(conn *Connection)

type TLSStatus

type TLSStatus struct {
	Completed bool
	Packet
	Error error
}

Jump to

Keyboard shortcuts

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