quic

package
v0.0.0-...-f9f9ce7 Latest Latest
Warning

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

Go to latest
Published: Sep 26, 2020 License: MIT, MIT Imports: 26 Imported by: 0

README

A QUIC implementation in pure Go

Please read https://multipath-quic.org/2017/12/09/artifacts-available.html to figure out how to setup the code.

Godoc Reference Linux Build Status Windows Build Status Code Coverage

quic-go is an implementation of the QUIC protocol in Go.

Roadmap

quic-go is compatible with the current version(s) of Google Chrome and QUIC as deployed on Google's servers. We're actively tracking the development of the Chrome code to ensure compatibility as the protocol evolves. In that process, we're dropping support for old QUIC versions. As Google's QUIC versions are expected to converge towards the IETF QUIC draft, quic-go will eventually implement that draft.

Guides

We currently support Go 1.9+.

Installing and updating dependencies:

go get -t -u ./...

Running tests:

go test ./...
Running the example server
go run example/main.go -www /var/www/

Using the quic_client from chromium:

quic_client --host=127.0.0.1 --port=6121 --v=1 https://quic.clemente.io

Using Chrome:

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --user-data-dir=/tmp/chrome --no-proxy-server --enable-quic --origin-to-force-quic-on=quic.clemente.io:443 --host-resolver-rules='MAP quic.clemente.io:443 127.0.0.1:6121' https://quic.clemente.io
QUIC without HTTP/2

Take a look at this echo example.

Using the example client
go run example/client/main.go https://clemente.io

Usage

As a server

See the example server or try out Caddy (from version 0.9, instructions here). Starting a QUIC server is very similar to the standard lib http in go:

http.Handle("/", http.FileServer(http.Dir(wwwDir)))
h2quic.ListenAndServeQUIC("localhost:4242", "/path/to/cert/chain.pem", "/path/to/privkey.pem", nil)
As a client

See the example client. Use a h2quic.RoundTripper as a Transport in a http.Client.

http.Client{
  Transport: &h2quic.RoundTripper{},
}

Contributing

We are always happy to welcome new contributors! We have a number of self-contained issues that are suitable for first-time contributors, they are tagged with want-help. If you have any questions, please feel free to reach out by opening an issue or leaving a comment.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// The QUIC versions that can be negotiated.
	// If not set, it uses all versions available.
	// Warning: This API should not be considered stable and will change soon.
	Versions []VersionNumber
	// Ask the server to truncate the connection ID sent in the Public Header.
	// This saves 8 bytes in the Public Header in every packet. However, if the IP address of the server changes, the connection cannot be migrated.
	// Currently only valid for the client.
	RequestConnectionIDTruncation bool
	// HandshakeTimeout is the maximum duration that the cryptographic handshake may take.
	// If the timeout is exceeded, the connection is closed.
	// If this value is zero, the timeout is set to 10 seconds.
	HandshakeTimeout time.Duration
	// IdleTimeout is the maximum duration that may pass without any incoming network activity.
	// This value only applies after the handshake has completed.
	// If the timeout is exceeded, the connection is closed.
	// If this value is zero, the timeout is set to 30 seconds.
	IdleTimeout time.Duration
	// AcceptCookie determines if a Cookie is accepted.
	// It is called with cookie = nil if the client didn't send an Cookie.
	// If not set, it verifies that the address matches, and that the Cookie was issued within the last 24 hours.
	// This option is only valid for the server.
	AcceptCookie func(clientAddr net.Addr, cookie *Cookie) bool
	// MaxReceiveStreamFlowControlWindow is the maximum stream-level flow control window for receiving data.
	// If this value is zero, it will default to 1 MB for the server and 6 MB for the client.
	MaxReceiveStreamFlowControlWindow uint64
	// MaxReceiveConnectionFlowControlWindow is the connection-level flow control window for receiving data.
	// If this value is zero, it will default to 1.5 MB for the server and 15 MB for the client.
	MaxReceiveConnectionFlowControlWindow uint64
	// KeepAlive defines whether this peer will periodically send PING frames to keep the connection alive.
	KeepAlive bool
	// Should we cache handshake parameters? If no cache available, should we create one?
	CacheHandshake bool
	// Should the host try to create new paths, if possible?
	CreatePaths bool
	// Path scheduler, default multipath
	PathScheduler string
}

Config contains all configuration data needed for a QUIC server or client.

type Cookie = handshake.Cookie

A Cookie can be used to verify the ownership of the client address.

type Listener

type Listener interface {
	// Close the server, sending CONNECTION_CLOSE frames to each peer.
	Close() error
	// Addr returns the local network addr that the server is listening on.
	Addr() net.Addr
	// Accept returns new sessions. It should be called in a loop.
	Accept() (Session, error)
}

A Listener for incoming QUIC connections

func Listen

func Listen(pconn net.PacketConn, tlsConf *tls.Config, config *Config) (Listener, error)

Listen listens for QUIC connections on a given net.PacketConn. The listener is not active until Serve() is called. The tls.Config must not be nil, the quic.Config may be nil.

func ListenAddr

func ListenAddr(addr string, tlsConf *tls.Config, config *Config) (Listener, error)

ListenAddr creates a QUIC server listening on a given address. The listener is not active until Serve() is called. The tls.Config must not be nil, the quic.Config may be nil.

func ListenAddrImpl

func ListenAddrImpl(addr string, tlsConf *tls.Config, config *Config, pconnMgrArg *pconnManager) (Listener, error)

ListenAddrImpl creates a QUIC server listening on a given address. The listener is not active until Serve() is called. The tls.Config must not be nil, the quic.Config may be nil. The pconnManager may be nil

func ListenImpl

func ListenImpl(pconn net.PacketConn, tlsConf *tls.Config, config *Config, pconnMgrArg *pconnManager) (Listener, error)

ListenImpl listens for QUIC connections on a given net.PacketConn. The listener is not active until Serve() is called. The tls.Config must not be nil, the quic.Config may be nil. pconnManager may be nil

type NonFWSession

type NonFWSession interface {
	Session
	WaitUntilHandshakeComplete() error
}

A NonFWSession is a QUIC connection between two peers half-way through the handshake. The communication is encrypted, but not yet forward secure.

func DialAddrNonFWSecure

func DialAddrNonFWSecure(
	addr string,
	tlsConf *tls.Config,
	config *Config,
) (NonFWSession, error)

DialAddrNonFWSecure establishes a new QUIC connection to a server. The hostname for SNI is taken from the given address.

func DialNonFWSecure

func DialNonFWSecure(
	pconn net.PacketConn,
	remoteAddr net.Addr,
	host string,
	tlsConf *tls.Config,
	config *Config,
	pconnMgrArg *pconnManager,
) (NonFWSession, error)

DialNonFWSecure establishes a new non-forward-secure QUIC connection to a server using a net.PacketConn. The host parameter is used for SNI.

type PathStats

type PathStats struct {
	PathID          uint8
	SmoothedRTT     float64 // in seconds, if wanted in ms use time.Duration
	Bandwidth       uint64
	Packets         uint64
	Retransmissions uint64
	Losses          uint64
}

PathStats combined

type Priority

type Priority struct {
	Dependency protocol.StreamID
	Weight     uint8
	Exclusive  bool
}

A Priority is a stream priority in QUIC

type Request

type Request struct {
	StreamID    protocol.StreamID
	RequestPath string
	Path1       *PathStats
	Path2       *PathStats
}

Request ...

type Response

type Response struct {
	StreamID protocol.StreamID
	PathID   uint8
}

Response ...

type Session

type Session interface {
	// AcceptStream returns the next stream opened by the peer, blocking until one is available.
	// Since stream 1 is reserved for the crypto stream, the first stream is either 2 (for a client) or 3 (for a server).
	AcceptStream() (Stream, error)
	// OpenStream opens a new QUIC stream, returning a special error when the peer's concurrent stream limit is reached.
	// New streams always have the smallest possible stream ID.
	// TODO: Enable testing for the special error
	OpenStream() (Stream, error)
	// OpenStreamSync opens a new QUIC stream, blocking until the peer's concurrent stream limit allows a new stream to be opened.
	// It always picks the smallest possible stream ID.
	OpenStreamSync() (Stream, error)
	//OpenStreamPrioritySync opens a new QUIC stream with priority
	OpenStreamPrioritySync(*protocol.Priority) (Stream, error)
	//OpenStreamPrioritySizeSync opens a new QUIC stream with priority and size
	OpenStreamPrioritySizeSync(*protocol.Priority) (Stream, error)
	// LocalAddr returns the local address.
	LocalAddr() net.Addr
	// RemoteAddr returns the address of the peer.
	RemoteAddr() net.Addr
	// Close closes the connection. The error will be sent to the remote peer in a CONNECTION_CLOSE frame. An error value of nil is allowed and will cause a normal PeerGoingAway to be sent.
	Close(error) error
	// The context is cancelled when the session is closed.
	// Warning: This API should not be considered stable and might change soon.
	Context() context.Context
}

A Session is a QUIC connection between two peers.

func Dial

func Dial(
	pconn net.PacketConn,
	remoteAddr net.Addr,
	host string,
	tlsConf *tls.Config,
	config *Config,
	pconnMgrArg *pconnManager,
) (Session, error)

Dial establishes a new QUIC connection to a server using a net.PacketConn. The host parameter is used for SNI.

func DialAddr

func DialAddr(addr string, tlsConf *tls.Config, config *Config) (Session, error)

DialAddr establishes a new QUIC connection to a server. The hostname for SNI is taken from the given address.

type Stream

type Stream interface {
	// Read reads data from the stream.
	// Read can be made to time out and return a net.Error with Timeout() == true
	// after a fixed time limit; see SetDeadline and SetReadDeadline.
	io.Reader
	// Write writes data to the stream.
	// Write can be made to time out and return a net.Error with Timeout() == true
	// after a fixed time limit; see SetDeadline and SetWriteDeadline.
	io.Writer
	io.Closer
	StreamID() StreamID
	Priority() *protocol.Priority
	Size() protocol.ByteCount
	LenOfDataForWriting() protocol.ByteCount
	// Reset closes the stream with an error.
	Reset(error)
	// The context is canceled as soon as the write-side of the stream is closed.
	// This happens when Close() is called, or when the stream is reset (either locally or remotely).
	// Warning: This API should not be considered stable and might change soon.
	Context() context.Context
	// SetReadDeadline sets the deadline for future Read calls and
	// any currently-blocked Read call.
	// A zero value for t means Read will not time out.
	SetReadDeadline(t time.Time) error
	// SetWriteDeadline sets the deadline for future Write calls
	// and any currently-blocked Write call.
	// Even if write times out, it may return n > 0, indicating that
	// some of the data was successfully written.
	// A zero value for t means Write will not time out.
	SetWriteDeadline(t time.Time) error
	// SetDeadline sets the read and write deadlines associated
	// with the connection. It is equivalent to calling both
	// SetReadDeadline and SetWriteDeadline.
	SetDeadline(t time.Time) error
	// GetBytesSent returns the number of bytes of the stream that were sent to the peer
	GetBytesSent() (protocol.ByteCount, error)
	// GetBytesRetrans returns the number of bytes of the stream that were retransmitted to the peer
	GetBytesRetrans() (protocol.ByteCount, error)
}

Stream is the interface implemented by QUIC streams

type StreamID

type StreamID = protocol.StreamID

The StreamID is the ID of a QUIC stream.

type StreamInfo

type StreamInfo struct {
	StreamID       uint32
	ObjectID       string
	CompletionTime float64
	Path           string
}

StreamInfo combined

type StreamToPath

type StreamToPath map[protocol.StreamID][]protocol.PathID

StreamToPath stores scheduling results of stream to path. A stream can be scheduled onto multiple paths

func (StreamToPath) Add

func (streamToPath StreamToPath) Add(sid protocol.StreamID, pid protocol.PathID) error

Add adds a item to streamToPath and avoid duplicate

func (StreamToPath) Delete

func (streamToPath StreamToPath) Delete(i protocol.StreamID) error

Delete deletes all record of stream i from streamToPath

func (StreamToPath) DeleteOne

func (streamToPath StreamToPath) DeleteOne(i protocol.StreamID, value protocol.PathID) error

DeleteOne deletes a item from streamToPath

func (StreamToPath) Find

func (streamToPath StreamToPath) Find(sid protocol.StreamID, pid protocol.PathID) (bool, error)

Find checks whether the entry is contained in streamToPath

func (StreamToPath) Get

func (streamToPath StreamToPath) Get(i protocol.StreamID) ([]protocol.PathID, error)

Get returns the scheduled path IDs of stream i

type VersionNumber

type VersionNumber = protocol.VersionNumber

A VersionNumber is a QUIC version number.

type ZClient

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

ZClient ZMQ-Client

func NewClient

func NewClient() (client *ZClient)

NewClient instantiates a new zmq.Request client and a zmq.Poller

func (*ZClient) Bind

func (client *ZClient) Bind(endpoint string)

Bind ...

func (*ZClient) Close

func (client *ZClient) Close()

Close ...

func (*ZClient) Connect

func (client *ZClient) Connect(endpoint string)

Connect ...

func (*ZClient) Request

func (client *ZClient) Request(request *Request) (err error)

Request ...

func (*ZClient) Response

func (client *ZClient) Response() (response *Response, err error)

Response ...

type ZPublisher

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

ZPublisher ZMQ-Client

func NewPublisher

func NewPublisher() (publisher *ZPublisher)

NewPublisher instantiates a new zmq.Publisher and a zmq.Poller

func (*ZPublisher) Bind

func (publisher *ZPublisher) Bind(endpoint string)

Bind ...

func (*ZPublisher) Close

func (publisher *ZPublisher) Close()

Close ...

func (*ZPublisher) Connect

func (publisher *ZPublisher) Connect(endpoint string)

Connect ..

func (*ZPublisher) Publish

func (publisher *ZPublisher) Publish(streamInfo *StreamInfo) (err error)

Publish messages so everyone listening can receive

func (*ZPublisher) RecvConfirmation

func (publisher *ZPublisher) RecvConfirmation() (err error)

RecvConfirmation ...

Jump to

Keyboard shortcuts

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