diff --git a/client.go b/client.go index 70827e5e..5729fede 100644 --- a/client.go +++ b/client.go @@ -36,7 +36,8 @@ var ( errCloseSessionForNewVersion = errors.New("closing session in order to recreate it with a new version") ) -// Dial establishes a new QUIC connection to a server +// Dial establishes a new QUIC connection to a server using a net.PacketConn. +// The host parameter is used for SNI. func Dial(pconn net.PacketConn, remoteAddr net.Addr, host string, config *Config) (Session, error) { connID, err := utils.GenerateConnectionID() if err != nil { @@ -68,9 +69,10 @@ func Dial(pconn net.PacketConn, remoteAddr net.Addr, host string, config *Config return c.establishConnection() } -// DialAddr establishes a new QUIC connection to a server -func DialAddr(hostname string, config *Config) (Session, error) { - udpAddr, err := net.ResolveUDPAddr("udp", hostname) +// DialAddr establishes a new QUIC connection to a server. +// The hostname for SNI is taken from the given address. +func DialAddr(addr string, config *Config) (Session, error) { + udpAddr, err := net.ResolveUDPAddr("udp", addr) if err != nil { return nil, err } @@ -80,7 +82,7 @@ func DialAddr(hostname string, config *Config) (Session, error) { return nil, err } - return Dial(udpConn, udpAddr, hostname, config) + return Dial(udpConn, udpAddr, addr, config) } func (c *client) establishConnection() (Session, error) { diff --git a/interface.go b/interface.go index 4f7fe5d4..c7ebcb4e 100644 --- a/interface.go +++ b/interface.go @@ -8,26 +8,31 @@ import ( "github.com/lucas-clemente/quic-go/protocol" ) -// Stream is the interface for QUIC streams +// Stream is the interface implemented by QUIC streams type Stream interface { io.Reader io.Writer io.Closer StreamID() protocol.StreamID + // Reset closes the stream with an error. Reset(error) } -// A Session is a QUIC Session +// A Session is a QUIC connection between two peers. type Session interface { - // get the next stream opened by the client - // first stream returned has StreamID 3 + // 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) - // guaranteed to return the smallest unopened stream - // special error for "too many streams, retry later" + // OpenStream opens a new QUIC stream, returning a special error when the peeer'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) - // blocks until a new stream can be opened, if the maximum number of stream is opened + // 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) + // RemoteAddr returns the address of the peer. RemoteAddr() net.Addr + // Close closes the connection. An error value of nil is allowed. Close(error) error } @@ -45,20 +50,24 @@ const ( ConnStateForwardSecure ) -// ConnStateCallback is called every time the connection moves to another connection state -// the callback is called in a new go routine +// ConnStateCallback is called every time the connection moves to another connection state. type ConnStateCallback func(Session, ConnState) -// Config is the configuration for QUIC +// Config contains all configuration data needed for a QUIC server or client. type Config struct { TLSConfig *tls.Config - // will be called in a separate goroutine + // ConnStateCallback will be called when the QUIC version is successfully negotiated or when the encryption level changes. + // If this field is not set, the Dial functions will return only when the connection is forward secure. + // The callback may be called in a separate goroutine. ConnState ConnStateCallback } -// A Listener listens for incoming QUIC connections +// A Listener for incoming QUIC connections 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 + // Serve starts the main server loop, and blocks until a network error occurs or the server is closed. Serve() error } diff --git a/public_header.go b/public_header.go index 3c7585e0..e8b26e56 100644 --- a/public_header.go +++ b/public_header.go @@ -17,7 +17,7 @@ var ( errGetLengthNotForVersionNegotiation = errors.New("PublicHeader: GetLength cannot be called for VersionNegotiation packets") ) -// The PublicHeader of a QUIC packet +// The PublicHeader of a QUIC packet. type PublicHeader struct { Raw []byte ConnectionID protocol.ConnectionID @@ -31,7 +31,7 @@ type PublicHeader struct { DiversificationNonce []byte } -// Write writes a public header +// Write writes a public header. Warning: This API should not be considered stable and will change soon. func (h *PublicHeader) Write(b *bytes.Buffer, version protocol.VersionNumber, pers protocol.Perspective) error { publicFlagByte := uint8(0x00) @@ -109,8 +109,9 @@ func (h *PublicHeader) Write(b *bytes.Buffer, version protocol.VersionNumber, pe return nil } -// ParsePublicHeader parses a QUIC packet's public header -// the packetSentBy is the perspective of the peer that sent this PublicHeader, i.e. if we're the server, packetSentBy should be PerspectiveClient +// ParsePublicHeader parses a QUIC packet's public header. +// The packetSentBy is the perspective of the peer that sent this PublicHeader, i.e. if we're the server, packetSentBy should be PerspectiveClient. +// Warning: This API should not be considered stable and will change soon. func ParsePublicHeader(b *bytes.Reader, packetSentBy protocol.Perspective) (*PublicHeader, error) { header := &PublicHeader{} @@ -216,8 +217,8 @@ func ParsePublicHeader(b *bytes.Reader, packetSentBy protocol.Perspective) (*Pub return header, nil } -// GetLength gets the length of the publicHeader in bytes -// can only be called for regular packets +// GetLength gets the length of the publicHeader in bytes. +// It can only be called for regular packets. func (h *PublicHeader) GetLength(pers protocol.Perspective) (protocol.ByteCount, error) { if h.VersionFlag && h.ResetFlag { return 0, errResetAndVersionFlagSet diff --git a/server.go b/server.go index 91c346e4..4cd54877 100644 --- a/server.go +++ b/server.go @@ -41,7 +41,8 @@ type server struct { var _ Listener = &server{} -// ListenAddr listens for QUIC connections on a given address +// ListenAddr creates a QUIC server listening on a given address. +// The listener is not active until Serve() is called. func ListenAddr(addr string, config *Config) (Listener, error) { udpAddr, err := net.ResolveUDPAddr("udp", addr) if err != nil { @@ -54,7 +55,8 @@ func ListenAddr(addr string, config *Config) (Listener, error) { return Listen(conn, config) } -// Listen listens for QUIC connections on a given net.PacketConn +// Listen listens for QUIC connections on a given net.PacketConn. +// The listener is not active until Serve() is called. func Listen(conn net.PacketConn, config *Config) (Listener, error) { certChain := crypto.NewCertChain(config.TLSConfig) kex, err := crypto.NewCurve25519KEX()