quiwi - QUIC implementation in Go.

Related tags

Network golang quic quiwi
Overview

Quiwi

Go Reference

QUIC transport protocol (https://quicwg.org/) implementation in Go. The goal is to provide low level APIs for applications or protocols using QUIC as a transport.

TLS 1.3 support is based on standard Go TLS package (https://github.com/golang/go/tree/master/src/crypto/tls), licensed under the 3-clause BSD license.

Features

  • Handshake with TLS 1.3
  • Version negotiation
  • Address validation
  • Loss detection
  • Congestion control
  • Streams
  • Flow control
  • ChaCha20 header protection
  • TLS session resumption
  • Anti-amplification
  • Unreliable datagram
  • qlog
  • Key update
  • Connection migration
  • Path MTU discovery
  • Zero RTT
  • HTTP/3

Development

Run tests:

go test ./...

Build command:

cd cmd/quiwi
go build

# To enable tracing
go build -tags quicdebug

# Check heap allocations
go build -gcflags '-m' 2>&1 | sort -V > debug.txt
go test -bench BenchmarkStream -run NONE -benchmem -memprofile mem.out -cpuprofile cpu.out
go tool pprof -http=:8080 mem.out

# Raspberry Pi Zero
GOOS=linux GOARCH=arm GOARM=6 CGO_ENABLED=0 go build

APIs

Package transport provides low-level APIs to control QUIC connections. Applications write input data to the connection and read output data for sending to peer.

config := transport.NewConfig()
server, err := transport.Accept(scid, odcid, config)
config := transport.NewConfig()
client, err := transport.Connect(scid, dcid, config)
for !conn.IsClosed() { // Loop until the connection is closed
	timeout := conn.Timeout()
	// (A negative timeout means that the timer should be disarmed)
	select {
		case data := <-dataChanel:  // Got data from peer
			n, err := conn.Write(data)
		case <-time.After(timeout): // Got receiving timeout
			n, err := conn.Write(nil)
	}
	// Get and process connection events
	events = conn.Events(events)
	for { // Loop until err != nil or n == 0
		n, err := conn.Read(buf)
		// Send buf[:n] to peer
	}
}

The root package quic instead provides high-level APIs where QUIC data are transferred over UDP. It also handles version negotiation, address validation and logging.

server := quic.NewServer(config)
server.SetHandler(handler)
err := server.ListenAndServe(address)
client := quic.NewClient(config)
client.SetHandler(handler)
err := client.ListenAndServe(address)
err = client.Connect(serverAddress)
// wait
client.Close()

Applications get connection events in the handler to control QUIC connections:

func (handler) Serve(conn *quic.Conn, events []transport.Event) {
	for _, e := range events {
		switch e.Type {
		case transport.EventConnOpen:
		case transport.EventConnClosed:
		}
	}
}

Server

See cmd/quiwi/server.go

Usage: quiwi server [arguments]
  -cache string
    	certificate cache directory when using ACME (default ".")
  -cert string
    	TLS certificate path
  -domains string
    	allowed host names for ACME (separated by a comma)
  -key string
    	TLS certificate key path
  -listen string
    	listen on the given IP:port (default ":4433")
  -qlog string
    	write logs to qlog file
  -retry
    	enable address validation using Retry packet
  -root string
    	root directory (default "www")
  -v int
    	log verbose: 0=off 1=error 2=info 3=debug 4=trace (default 2)

Examples:

# Listen on port 4433:
./quiwi server -cert ../../testdata/cert.pem -key ../../testdata/key.pem

# Automatically get certificate from Let's Encrypt:
# (This will also listen on TCP port 443 to handle "tls-alpn-01" challenge)
./quiwi server -domains example.com

Add SSLKEYLOGFILE=key.log to have TLS keys logged to file.

Client

See cmd/quiwi/client.go

Usage: quiwi client [arguments] <url>
  -cipher string
    	TLS 1.3 cipher suite, e.g. TLS_CHACHA20_POLY1305_SHA256
  -insecure
    	skip verifying server certificate
  -listen string
    	listen on the given IP:port (default "0.0.0.0:0")
  -qlog string
    	write logs to qlog file
  -root string
    	root download directory
  -v int
    	log verbose: 0=off 1=error 2=info 3=debug 4=trace (default 2)

Examples

./quiwi client https://quic.tech:4433/

./quiwi client -insecure https://localhost:4433/file.txt

Datagram

See cmd/quiwi/datagram.go

Usage: quiwi datagram [arguments] [url]
  -cert string
    	TLS certificate path (server only) (default "cert.pem")
  -data string
    	Datagram for sending (or from stdin if empty)
  -insecure
    	skip verifying server certificate (client only)
  -key string
    	TLS certificate key path (server only) (default "key.pem")
  -listen string
    	listen on the given IP:port (default "0.0.0.0:0")
  -v int
    	log verbose: 0=off 1=error 2=info 3=debug 4=trace (default 2)

Examples:

# Server
./quiwi datagram -listen 127.0.0.1:4433

# Client
./quiwi datagram -insecure -data hello https://127.0.0.1:4433

Testing

See interop/README.md

Fuzzing

See https://github.com/goburrow/quic-fuzz

Issues
  • Supported versions in version negotiation packet

    Supported versions in version negotiation packet

    Currently, quiwi uses the latest supported version (draft-32) during version negotiation. https://github.com/goburrow/quic/blob/c6121e3eccc2ea7aed57ed4ab064974cc730c5be/transport/packet.go#L479

    When I use quiwi as server, and quiche as client (supported draft-27 to draft-29), I got the unsupported version error because quiwi returns the version draft-32 which doesn't support in quiche. As I understand, quiwi supports the versions between the minimum version draft-29 to draft-32? If so, I will create a PR to add all versions draft-29 ... draft-32 to supportedVersions slice? Then quiwi and quiche will use draft-29. :)

    Or quiwi doesn't support the backward compatible with draft-29 to draft-31 after upgraded to draft-32?

    opened by xiaojian-hong 4
  • ack-frequency extensions

    ack-frequency extensions

    I could not find ack-frequency in the README feature list. Could you please confirm it was implemented or not?

    Adding: https://datatracker.ietf.org/doc/html/draft-ietf-quic-ack-frequency

    opened by vikulin 0
Releases(v0.0.8)
Owner
GoBurrow
Lightweight frameworks, libraries and tools written in Go (golang)
GoBurrow
A QUIC implementation in pure go

A QUIC implementation in pure Go quic-go is an implementation of the QUIC protocol in Go. It implements the IETF QUIC draft-29 and draft-32. Version c

Lucas Clemente 7.1k Aug 13, 2022
WebTransport implementation based on quic-go (https://datatracker.ietf.org/doc/draft-ietf-webtrans-http3/)

webtransport-go webtransport-go is an implementation of the WebTransport protocol, based on quic-go. It currently implements draft-02 of the specifica

Marten Seemann 67 Aug 16, 2022
Antenna RPC is an RPC protocol for distributed computing, it's based on QUIC and Colfer. its currently an WIP.

aRPC - Antenna Remote Procedure Call Antenna remote procedure call (aRPC) is an RPC protocol focused on distributed processing and HPC. aRPC is implem

Raphael de Carvalho Almeida 3 Jun 16, 2021
WebTransport-Go - WebTransport Server based on quic-go

WebTransportServer 箔quic-go撠鋆嚗其舀WebTransport隞乩臭蝙汞xample import ( "fmt"

dexter 5 Aug 16, 2022
A go implementation of the STUN client (RFC 3489 and RFC 5389)

go-stun go-stun is a STUN (RFC 3489, 5389) client implementation in golang (a.k.a. UDP hole punching). RFC 3489: STUN - Simple Traversal of User Datag

Cong Ding 511 Aug 12, 2022
Fast RFC 5389 STUN implementation in go

STUN Package stun implements Session Traversal Utilities for NAT (STUN) [RFC5389] protocol and client with no external dependencies and zero allocatio

null 488 Aug 15, 2022
Pure Go implementation of the WebRTC API

Pion WebRTC A pure Go implementation of the WebRTC API New Release Pion WebRTC v3.0.0 has been released! See the release notes to learn about new feat

Pion 9.7k Aug 14, 2022
A LWM2M Client and Server implementation (For Go/Golang)

Betwixt - A LWM2M Client and Server in Go Betwixt is a Lightweight M2M implementation written in Go OMA Lightweight M2M is a protocol from the Open Mo

Zubair Hamed 54 May 28, 2022
A Socket.IO backend implementation written in Go

go-socket.io The socketio package is a simple abstraction layer for different web browser- supported transport mechanisms. It is fully compatible with

Jukka-Pekka Kekkonen 406 Jul 23, 2022
A Windows named pipe implementation written in pure Go.

npipe Package npipe provides a pure Go wrapper around Windows named pipes. Windows named pipe documentation: http://msdn.microsoft.com/en-us/library/w

Nate Finch 250 Aug 3, 2022
An Etsy StatsD (https://github.com/etsy/statsd) implementation in Go

STATSD-GO Port of Etsy's statsd, written in Go. This was forked from https://github.com/amir/gographite to provide Ganglia submission support. USAGE U

Jeff Buchbinder 45 Mar 5, 2021
Implementation of the FTPS protocol for Golang.

FTPS Implementation for Go Information This implementation does not implement the full FTP/FTPS specification. Only a small subset. I have not done a

Marco Beierer 27 Mar 14, 2022
Yet another pinger: A high-performance ICMP ping implementation build on top of BPF technology.

yap Yet-Another-Pinger: A high-performance ICMP ping implementation build on top of BPF technology. yap uses the gopacket library to receive and handl

dongdong 39 Jun 21, 2022
Pure Go implementation of the WebRTC API

Pure Go implementation of the WebRTC API

Pion 9.7k Aug 8, 2022
Fast RFC 5389 STUN implementation in go

STUN Package stun implements Session Traversal Utilities for NAT (STUN) [RFC5389] protocol and client with no external dependencies and zero allocatio

null 488 Aug 15, 2022
Go implementation of the traceroute tool

tracesite tracesite is a simple Go implementation of the traceroute tool Check out the blog post on explanation Install : Download binary from release

Lakshay Kalbhor 108 Aug 4, 2022
The Go language implementation of gRPC. HTTP/2 based RPC

gRPC-Go The Go implementation of gRPC: A high performance, open source, general RPC framework that puts mobile and HTTP/2 first. For more information

grpc 16.6k Aug 11, 2022
Golang implementation of Sliding Window Algorithm for distributed rate limiting.

slidingwindow Golang implementation of Sliding Window Algorithm for distributed rate limiting. Installation $ go get -u github.com/RussellLuo/slidingw

Luo Peng 323 Jul 31, 2022
IPFS implementation in Go

go-ipfs What is IPFS? IPFS is a global, versioned, peer-to-peer filesystem. It combines good ideas from previous systems such as Git, BitTorrent, Kade

IPFS 14k Aug 9, 2022