Skip to content

Commit

Permalink
HTTP/3 update with draft-17
Browse files Browse the repository at this point in the history
  • Loading branch information
mpiraux committed Jan 21, 2019
1 parent acd73d2 commit 3e2cfe9
Show file tree
Hide file tree
Showing 28 changed files with 50 additions and 32 deletions.
2 changes: 1 addition & 1 deletion bin/test_suite/scenario_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func main() {

trace := qt.NewTrace(scenario.Name(), scenario.Version(), *host)

conn, err := qt.NewDefaultConnection(*host, strings.Split(*host, ":")[0], nil, scenario.IPv6()) // Raw IPv6 are not handled correctly
conn, err := qt.NewDefaultConnection(*host, strings.Split(*host, ":")[0], nil, scenario.IPv6(), scenario.HTTP3()) // Raw IPv6 are not handled correctly

if err == nil {
pcap, err := qt.StartPcapCapture(conn, *netInterface)
Expand Down
2 changes: 2 additions & 0 deletions common.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ import (
"math"
)

// TODO: Reconsider the use of global variables
var QuicVersion uint32 = 0xff000011 // See https://tools.ietf.org/html/draft-ietf-quic-transport-08#section-4
var QuicALPNToken = "hq-17" // See https://www.ietf.org/mail-archive/web/quic/current/msg01882.html
var QuicH3ALPNToken = "h3-17" // See https://tools.ietf.org/html/draft-ietf-quic-http-17#section-2.1

const (
MinimumInitialLength = 1252
Expand Down
18 changes: 14 additions & 4 deletions connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"net"
"os"
"sort"
"strings"
"unsafe"
)

Expand Down Expand Up @@ -46,6 +47,7 @@ type Connection struct {
SourceCID ConnectionID
DestinationCID ConnectionID
Version uint32
ALPN string

Token []byte
ResumptionTicket []byte
Expand Down Expand Up @@ -153,7 +155,8 @@ func (c *Connection) ProcessVersionNegotation(vn *VersionNegotiationPacket) erro
c.Logger.Printf("Versions received: %v\n", vn.SupportedVersions)
return errors.New("no appropriate version found")
}
QuicVersion, QuicALPNToken = version, fmt.Sprintf("hq-%02d", version & 0xff)
QuicVersion = version
QuicALPNToken = fmt.Sprintf("%s-%02d", strings.Split(c.ALPN, "-")[0], version & 0xff)
c.TransitionTo(QuicVersion, QuicALPNToken)
return nil
}
Expand Down Expand Up @@ -193,7 +196,8 @@ func (c *Connection) TransitionTo(version uint32, ALPN string) {
}
c.TLSTPHandler = NewTLSTransportParameterHandler(version, prevVersion)
c.Version = version
c.Tls = pigotls.NewConnection(c.ServerName, ALPN, c.ResumptionTicket)
c.ALPN = ALPN
c.Tls = pigotls.NewConnection(c.ServerName, c.ALPN, c.ResumptionTicket)
c.PacketNumber = make(map[PNSpace]PacketNumber)
c.LargestPNsReceived = make(map[PNSpace]PacketNumber)
c.LargestPNsAcknowledged = make(map[PNSpace]PacketNumber)
Expand Down Expand Up @@ -229,7 +233,7 @@ func EstablishUDPConnection(addr *net.UDPAddr) (*net.UDPConn, error) {
}
return udpConn, nil
}
func NewDefaultConnection(address string, serverName string, resumptionTicket []byte, useIPv6 bool) (*Connection, error) {
func NewDefaultConnection(address string, serverName string, resumptionTicket []byte, useIPv6 bool, negotiateHTTP3 bool) (*Connection, error) {
scid := make([]byte, 8, 8)
dcid := make([]byte, 8, 8)
rand.Read(scid)
Expand All @@ -251,7 +255,13 @@ func NewDefaultConnection(address string, serverName string, resumptionTicket []
return nil, err
}

c := NewConnection(serverName, QuicVersion, QuicALPNToken, scid, dcid, udpConn, resumptionTicket)
var c *Connection
if negotiateHTTP3 {
c = NewConnection(serverName, QuicVersion, QuicH3ALPNToken, scid, dcid, udpConn, resumptionTicket)
} else {
c = NewConnection(serverName, QuicVersion, QuicALPNToken, scid, dcid, udpConn, resumptionTicket)
}

c.UseIPv6 = useIPv6
c.Host = udpAddr
return c, nil
Expand Down
2 changes: 1 addition & 1 deletion http3/http3.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,9 @@ func ReadSetting(buffer *bytes.Reader) Setting {

const (
SETTINGS_HEADER_TABLE_SIZE = 0x01
SETTINGS_NUM_PLACEHOLDERS = 0x03
SETTINGS_MAX_HEADER_LIST_SIZE = 0x06
SETTINGS_QPACK_BLOCKED_STREAMS = 0x07
SETTINGS_NUM_PLACEHOLDERS = 0x08
)

type SETTINGS struct {
Expand Down
4 changes: 2 additions & 2 deletions scenarii/ack_ecn.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package scenarii

import (
"time"
qt "github.com/QUIC-Tracker/quic-tracker"
"github.com/QUIC-Tracker/quic-tracker/agents"
"time"
)

const (
Expand All @@ -19,7 +19,7 @@ type AckECNScenario struct {
}

func NewAckECNScenario() *AckECNScenario {
return &AckECNScenario{AbstractScenario{"ack_ecn", 1, false, nil}}
return &AckECNScenario{AbstractScenario{name: "ack_ecn", version: 1}}
}
func (s *AckECNScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
s.timeout = time.NewTimer(10 * time.Second)
Expand Down
2 changes: 1 addition & 1 deletion scenarii/ack_only.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type AckOnlyScenario struct {
}

func NewAckOnlyScenario() *AckOnlyScenario {
return &AckOnlyScenario{AbstractScenario{"ack_only", 1, false, nil}}
return &AckOnlyScenario{AbstractScenario{name: "ack_only", version: 1}}
}
func (s *AckOnlyScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
s.timeout = time.NewTimer(10 * time.Second)
Expand Down
2 changes: 1 addition & 1 deletion scenarii/address_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type AddressValidationScenario struct {
}

func NewAddressValidationScenario() *AddressValidationScenario {
return &AddressValidationScenario{AbstractScenario{"address_validation", 3, false, nil}}
return &AddressValidationScenario{AbstractScenario{name: "address_validation", version: 3}}
}
func (s *AddressValidationScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
s.timeout = time.NewTimer(10 * time.Second)
Expand Down
2 changes: 1 addition & 1 deletion scenarii/connection_migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type ConnectionMigrationScenario struct {
}

func NewConnectionMigrationScenario() *ConnectionMigrationScenario {
return &ConnectionMigrationScenario{AbstractScenario{"connection_migration", 1, false, nil}}
return &ConnectionMigrationScenario{AbstractScenario{name: "connection_migration", version: 1}}
}
func (s *ConnectionMigrationScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
s.timeout = time.NewTimer(10 * time.Second)
Expand Down
2 changes: 1 addition & 1 deletion scenarii/flow_control.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type FlowControlScenario struct {
}

func NewFlowControlScenario() *FlowControlScenario {
return &FlowControlScenario{AbstractScenario{"flow_control", 2, false, nil}}
return &FlowControlScenario{AbstractScenario{name: "flow_control", version: 2}}
}
func (s *FlowControlScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
s.timeout = time.NewTimer(10 * time.Second)
Expand Down
2 changes: 1 addition & 1 deletion scenarii/handshake.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type HandshakeScenario struct {
}

func NewHandshakeScenario() *HandshakeScenario {
return &HandshakeScenario{AbstractScenario{"handshake", 2, false, nil}}
return &HandshakeScenario{AbstractScenario{name: "handshake", version: 2}}
}
func (s *HandshakeScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
s.timeout = time.NewTimer(10 * time.Second)
Expand Down
2 changes: 1 addition & 1 deletion scenarii/handshake_v6.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type Handshakev6Scenario struct {
}

func NewHandshakev6Scenario() *Handshakev6Scenario {
return &Handshakev6Scenario{AbstractScenario{"handshake_v6", 2, true, nil}}
return &Handshakev6Scenario{AbstractScenario{name: "handshake_v6", version: 2, ipv6: true}}
}
func (s *Handshakev6Scenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
NewHandshakeScenario().Run(conn, trace, preferredUrl, debug)
Expand Down
2 changes: 1 addition & 1 deletion scenarii/http3_encoder_stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type HTTP3EncoderStreamScenario struct {
}

func NewHTTP3EncoderStreamScenario() *HTTP3EncoderStreamScenario {
return &HTTP3EncoderStreamScenario{AbstractScenario{"http3_encoder_stream", 1, false, nil}}
return &HTTP3EncoderStreamScenario{AbstractScenario{name: "http3_encoder_stream", version: 1, http3: true}}
}
func (s *HTTP3EncoderStreamScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
s.timeout = time.NewTimer(10 * time.Second)
Expand Down
3 changes: 2 additions & 1 deletion scenarii/http3_get.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ type HTTP3GETScenario struct {
}

func NewHTTP3GETScenario() *HTTP3GETScenario {
return &HTTP3GETScenario{AbstractScenario{"http3_get", 1, false, nil}}
return &HTTP3GETScenario{AbstractScenario{name: "http3_get", version: 1, http3: true}}
}
func (s *HTTP3GETScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
s.timeout = time.NewTimer(10 * time.Second)
conn.TLSTPHandler.MaxUniStreams = 3
conn.TransitionTo(qt.QuicVersion, qt.QuicH3ALPNToken)

http := agents.HTTPAgent{}
connAgents := s.CompleteHandshake(conn, trace, H3G_TLSHandshakeFailed, &http)
Expand Down
2 changes: 1 addition & 1 deletion scenarii/http3_uni_streams_limits.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type HTTP3UniStreamsLimitsScenario struct {
}

func NewHTTP3UniStreamsLimitsScenario() *HTTP3UniStreamsLimitsScenario {
return &HTTP3UniStreamsLimitsScenario{AbstractScenario{"http3_uni_streams_limits", 1, false, nil}}
return &HTTP3UniStreamsLimitsScenario{AbstractScenario{name: "http3_uni_streams_limits", version: 1, http3: true}}
}
func (s *HTTP3UniStreamsLimitsScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
s.timeout = time.NewTimer(10 * time.Second)
Expand Down
4 changes: 2 additions & 2 deletions scenarii/http_get_and_wait.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package scenarii
import (
qt "github.com/QUIC-Tracker/quic-tracker"

"time"
"fmt"
"time"
)

const (
Expand All @@ -25,7 +25,7 @@ type SimpleGetAndWaitScenario struct {
}

func NewSimpleGetAndWaitScenario() *SimpleGetAndWaitScenario {
return &SimpleGetAndWaitScenario{AbstractScenario{"http_get_and_wait", 1, false, nil}}
return &SimpleGetAndWaitScenario{AbstractScenario{name: "http_get_and_wait", version: 1}}
}

func (s *SimpleGetAndWaitScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
Expand Down
2 changes: 1 addition & 1 deletion scenarii/http_get_on_uni_stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type GetOnStream2Scenario struct {
}

func NewGetOnStream2Scenario() *GetOnStream2Scenario {
return &GetOnStream2Scenario{AbstractScenario{"http_get_on_uni_stream", 1, false, nil}}
return &GetOnStream2Scenario{AbstractScenario{name: "http_get_on_uni_stream", version: 1}}
}

func (s *GetOnStream2Scenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
Expand Down
2 changes: 1 addition & 1 deletion scenarii/key_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type KeyUpdateScenario struct {
}

func NewKeyUpdateScenario() *KeyUpdateScenario {
return &KeyUpdateScenario{AbstractScenario{"key_update", 1, false, nil}}
return &KeyUpdateScenario{AbstractScenario{name: "key_update", version: 1}}
}
func (s *KeyUpdateScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
s.timeout = time.NewTimer(10 * time.Second)
Expand Down
2 changes: 1 addition & 1 deletion scenarii/multi_stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type MultiStreamScenario struct {
}

func NewMultiStreamScenario() *MultiStreamScenario {
return &MultiStreamScenario{AbstractScenario{"multi_stream", 1, false, nil}}
return &MultiStreamScenario{AbstractScenario{name: "multi_stream", version: 1}}
}
func (s *MultiStreamScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
s.timeout = time.NewTimer(10 * time.Second)
Expand Down
2 changes: 1 addition & 1 deletion scenarii/new_connection_id.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type NewConnectionIDScenario struct {
}

func NewNewConnectionIDScenario() *NewConnectionIDScenario {
return &NewConnectionIDScenario{AbstractScenario{"new_connection_id", 1, false, nil}}
return &NewConnectionIDScenario{AbstractScenario{name: "new_connection_id", version: 1}}
}
func (s *NewConnectionIDScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
// TODO: Flag NEW_CONNECTION_ID frames sent before TLS Handshake complete
Expand Down
2 changes: 1 addition & 1 deletion scenarii/padding.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type PaddingScenario struct {
}

func NewPaddingScenario() *PaddingScenario {
return &PaddingScenario{AbstractScenario{"padding", 1, false, nil}}
return &PaddingScenario{AbstractScenario{name: "padding", version: 1}}
}
func (s *PaddingScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
s.timeout = time.NewTimer(10 * time.Second)
Expand Down
2 changes: 1 addition & 1 deletion scenarii/retire_connection_id.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type RetireConnectionIDScenario struct {
}

func NewRetireConnectionIDScenario() *RetireConnectionIDScenario {
return &RetireConnectionIDScenario{AbstractScenario{"retire_connection_id", 1, false, nil}}
return &RetireConnectionIDScenario{AbstractScenario{name: "retire_connection_id", version: 1}}
}
func (s *RetireConnectionIDScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
s.timeout = time.NewTimer(10 * time.Second)
Expand Down
5 changes: 5 additions & 0 deletions scenarii/scenario.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type Scenario interface {
Name() string
Version() int
IPv6() bool
HTTP3() bool
Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool)
Timeout() *time.Timer
}
Expand All @@ -31,6 +32,7 @@ type AbstractScenario struct {
name string
version int
ipv6 bool
http3 bool
timeout *time.Timer
}

Expand All @@ -43,6 +45,9 @@ func (s *AbstractScenario) Version() int {
func (s *AbstractScenario) IPv6() bool {
return s.ipv6
}
func (s *AbstractScenario) HTTP3() bool {
return s.http3
}
func (s *AbstractScenario) Timeout() *time.Timer {
return s.timeout
}
Expand Down
2 changes: 1 addition & 1 deletion scenarii/stop_sending_frame_on_receive_stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type StopSendingOnReceiveStreamScenario struct {
}

func NewStopSendingOnReceiveStreamScenario() *StopSendingOnReceiveStreamScenario {
return &StopSendingOnReceiveStreamScenario{AbstractScenario{"stop_sending_frame_on_receive_stream", 1, false, nil}}
return &StopSendingOnReceiveStreamScenario{AbstractScenario{name: "stop_sending_frame_on_receive_stream", version: 1}}
}

func (s *StopSendingOnReceiveStreamScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
Expand Down
2 changes: 1 addition & 1 deletion scenarii/stream_opening_reordering.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type StreamOpeningReorderingScenario struct {
}

func NewStreamOpeningReorderingScenario() *StreamOpeningReorderingScenario {
return &StreamOpeningReorderingScenario{AbstractScenario{"stream_opening_reordering", 2, false, nil}}
return &StreamOpeningReorderingScenario{AbstractScenario{name: "stream_opening_reordering", version: 2}}
}
func (s *StreamOpeningReorderingScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
s.timeout = time.NewTimer(10 * time.Second)
Expand Down
2 changes: 1 addition & 1 deletion scenarii/transport_parameters.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type TransportParameterScenario struct {
}

func NewTransportParameterScenario() *TransportParameterScenario {
return &TransportParameterScenario{AbstractScenario{"transport_parameters", 3, false, nil}}
return &TransportParameterScenario{AbstractScenario{name: "transport_parameters", version: 3}}
}
func (s *TransportParameterScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
s.timeout = time.NewTimer(10 * time.Second)
Expand Down
2 changes: 1 addition & 1 deletion scenarii/unsupported_tls_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type UnsupportedTLSVersionScenario struct {
}

func NewUnsupportedTLSVersionScenario() *UnsupportedTLSVersionScenario {
return &UnsupportedTLSVersionScenario{AbstractScenario{"unsupported_tls_version", 1, false, nil}}
return &UnsupportedTLSVersionScenario{AbstractScenario{name: "unsupported_tls_version", version: 1}}
}
func (s *UnsupportedTLSVersionScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
s.timeout = time.NewTimer(10 * time.Second)
Expand Down
2 changes: 1 addition & 1 deletion scenarii/version_negotiation.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type VersionNegotiationScenario struct {
}

func NewVersionNegotiationScenario() *VersionNegotiationScenario {
return &VersionNegotiationScenario{AbstractScenario{"version_negotiation", 2, false, nil}}
return &VersionNegotiationScenario{AbstractScenario{name: "version_negotiation", version: 2}}
}
func (s *VersionNegotiationScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
s.timeout = time.NewTimer(10 * time.Second)
Expand Down
4 changes: 2 additions & 2 deletions scenarii/zero_rtt.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type ZeroRTTScenario struct {
}

func NewZeroRTTScenario() *ZeroRTTScenario {
return &ZeroRTTScenario{AbstractScenario{"zero_rtt", 1, false, nil}}
return &ZeroRTTScenario{AbstractScenario{name: "zero_rtt", version: 1}}
}
func (s *ZeroRTTScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl string, debug bool) {
s.timeout = time.NewTimer(10 * time.Second)
Expand Down Expand Up @@ -58,7 +58,7 @@ func (s *ZeroRTTScenario) Run(conn *qt.Connection, trace *qt.Trace, preferredUrl
rh, sh, token := conn.ReceivedPacketHandler, conn.SentPacketHandler, conn.Token

var err error
conn, err = qt.NewDefaultConnection(conn.Host.String(), conn.ServerName, ticket, s.ipv6)
conn, err = qt.NewDefaultConnection(conn.Host.String(), conn.ServerName, ticket, s.ipv6, false)
conn.ReceivedPacketHandler = rh
conn.SentPacketHandler = sh
conn.Token = token
Expand Down

0 comments on commit 3e2cfe9

Please sign in to comment.