Skip to content

Commit

Permalink
draft-19 support
Browse files Browse the repository at this point in the history
  • Loading branch information
mpiraux committed Apr 23, 2019
1 parent 1af121e commit 728f1a0
Show file tree
Hide file tree
Showing 13 changed files with 133 additions and 137 deletions.
2 changes: 1 addition & 1 deletion agents/closing_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type ClosingAgent struct {
func (a *ClosingAgent) Run(conn *Connection) { // TODO: Observe incoming CC and AC
a.Init("ClosingAgent", conn.OriginalDestinationCID)
a.conn = conn
a.IdleDuration = time.Duration(a.conn.TLSTPHandler.IdleTimeout) * time.Second
a.IdleDuration = time.Duration(a.conn.TLSTPHandler.IdleTimeout) * time.Millisecond
a.IdleTimeout = time.NewTimer(a.IdleDuration)

incomingPackets := conn.IncomingPackets.RegisterNewChan(1000)
Expand Down
32 changes: 18 additions & 14 deletions agents/http3_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func (a *HTTP3Agent) Run(conn *Connection) {
a.peerControlStreamID = HTTPNoStream
peerControlStream := make(chan interface{}, 1000)
peerControlStreamBuffer := new(bytes.Buffer)
a.conn.Streams.Send(a.controlStreamID, []byte{'C'}, false)
a.conn.Streams.Send(a.controlStreamID, []byte{http3.StreamTypeControl}, false)
a.sendFrameOnStream(http3.NewSETTINGS(nil), a.controlStreamID, false)

a.streamData = make(chan streamData)
Expand All @@ -97,7 +97,7 @@ func (a *HTTP3Agent) Run(conn *Connection) {
for _, f := range p.(Framer).GetAll(StreamType) {
s := f.(*StreamFrame)
if s.Offset == 0 && s.StreamId&0x2 == 2 {
if s.StreamData[0] == 'C' {
if s.StreamData[0] == http3.StreamTypeControl {
if a.peerControlStreamID != HTTPNoStream {
a.Logger.Printf("Peer attempted to open another control stream on stream %d\n", s.StreamId)
continue
Expand Down Expand Up @@ -150,9 +150,9 @@ func (a *HTTP3Agent) Run(conn *Connection) {
}
settingsReceived = true
for _, s := range f.Settings {
if s.Identifier == http3.SETTINGS_HEADER_TABLE_SIZE {
if s.Identifier.Value == http3.SETTINGS_HEADER_TABLE_SIZE {
settingsHeaderTableSize = s.Value.Value
} else if s.Identifier == http3.SETTINGS_QPACK_BLOCKED_STREAMS {
} else if s.Identifier.Value == http3.SETTINGS_QPACK_BLOCKED_STREAMS {
settingsQPACKBlockedStreams = s.Value.Value
}
}
Expand Down Expand Up @@ -194,15 +194,19 @@ func (a *HTTP3Agent) sendFrameOnStream(frame http3.HTTPFrame, streamID uint64, f
a.conn.Streams.Send(streamID, buf.Bytes(), fin)
}
func (a *HTTP3Agent) attemptDecoding(streamID uint64, buffer *bytes.Buffer) {
var l VarInt
var err error
for l, err = peekVarInt(buffer); err == nil && buffer.Len() >= l.Length+1+int(l.Value); l, err = peekVarInt(buffer) {
reader := bytes.NewReader(buffer.Next(l.Length + 1 + int(l.Value)))
frame := http3.ReadHTTPFrame(reader)
a.FrameReceived.Submit(HTTP3FrameReceived{streamID, frame})
}
if err == nil {
a.Logger.Printf("Unable to parse %d byte-long frame on stream %d, %d bytes missing\n", l.Value, streamID, int(l.Value)-(buffer.Len()-l.Length-1))
r := bytes.NewReader(buffer.Bytes())
t, err1 := ReadVarInt(r)
l, err2 := ReadVarInt(r)

if err1 == nil && err2 == nil {
if buffer.Len() >= t.Length + l.Length + int(l.Value) {
r = bytes.NewReader(buffer.Next(t.Length + l.Length + int(l.Value)))
f := http3.ReadHTTPFrame(r)
a.FrameReceived.Submit(HTTP3FrameReceived{streamID, f})
a.attemptDecoding(streamID, buffer)
} else {
a.Logger.Printf("Unable to parse %d byte-long frame on stream %d, %d bytes missing\n", t.Value, streamID, int(t.Value)-(buffer.Len()-t.Length-1))
}
}
}
func (a *HTTP3Agent) checkResponse(response *HTTP3Response) {
Expand Down Expand Up @@ -238,6 +242,7 @@ func (a *HTTP3Agent) SendRequest(path, method, authority string, headers map[str
a.responseBuffer[streamID] = response

go func() { // Pipes the data from the response stream to the agent
defer stream.ReadChan.Unregister(streamChan)
for {
select {
case i := <-streamChan:
Expand All @@ -256,7 +261,6 @@ func (a *HTTP3Agent) SendRequest(path, method, authority string, headers map[str
}

}
stream.ReadChan.Unregister(streamChan)
}()

a.QPACK.EncodeHeaders <- DecodedHeaders{streamID, hdrs}
Expand Down
10 changes: 6 additions & 4 deletions agents/qpack_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ type QPACKAgent struct {

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

func (a *QPACKAgent) Run(conn *Connection) {
Expand Down Expand Up @@ -87,7 +89,7 @@ func (a *QPACKAgent) Run(conn *Connection) {
for _, f := range p.(Framer).GetAll(StreamType) {
s := f.(*StreamFrame)
if s.Offset == 0 && s.StreamId&0x2 == 2 {
if s.StreamData[0] == 'H' {
if s.StreamData[0] == QPACKEncoderStreamValue {
if peerEncoderStreamId != QPACKNoStream {
a.Logger.Printf("Peer attempted to open another encoder stream on stream %d\n", s.StreamId)
continue
Expand All @@ -98,7 +100,7 @@ func (a *QPACKAgent) Run(conn *Connection) {
if s.Length > 1 {
peerEncoderStream <- s.StreamData[1:]
}
} else if s.StreamData[0] == 'h' {
} else if s.StreamData[0] == QPACKDecoderStreamValue {
if peerDecoderStreamId != QPACKNoStream {
a.Logger.Printf("Peer attempted to open another decoder stream on stream %d\n", s.StreamId)
continue
Expand Down Expand Up @@ -162,8 +164,8 @@ func (a *QPACKAgent) Run(conn *Connection) {
}()

if !a.DisableStreams {
conn.Streams.Send(a.EncoderStreamID, []byte{'H'}, false)
conn.Streams.Send(a.DecoderStreamID, []byte{'h'}, false)
conn.Streams.Send(a.EncoderStreamID, []byte{QPACKEncoderStreamValue}, false)
conn.Streams.Send(a.DecoderStreamID, []byte{QPACKDecoderStreamValue}, false)
}
}
func (a *QPACKAgent) InitEncoder(headerTableSize uint, dynamicTablesize uint, maxRiskedStreams uint, opts uint32) {
Expand Down
6 changes: 6 additions & 0 deletions agents/recovery_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ func (a *RecoveryAgent) Run(conn *Connection) {
if len(frames) > 0 {
a.retransmissionBuffer[p.PNSpace()][p.Header().PacketNumber()] = *NewRetransmittableFrames(frames, p.EncryptionLevel())
}
if p.Contains(ConnectionCloseType) || p.Contains(ApplicationCloseType) {
a.Logger.Println("Connection is closing")
return
}
}
case i := <-eLAvailable:
eL := i.(DirectionalEncryptionLevel)
Expand All @@ -93,6 +97,8 @@ func (a *RecoveryAgent) Run(conn *Connection) {
a.retransmissionBuffer[PNSpaceInitial] = make(map[PacketNumber]RetransmittableFrames)
a.retransmissionBuffer[PNSpaceHandshake] = make(map[PacketNumber]RetransmittableFrames)
}
case <-a.conn.ConnectionClosed:
return
case <-a.close:
return
}
Expand Down
6 changes: 3 additions & 3 deletions bin/http/http_get.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ func main() {

t := time.NewTimer(time.Duration(*timeout) * time.Second)
conn, err := m.NewDefaultConnection(*address, (*address)[:strings.LastIndex(*address, ":")], nil, *useIPv6, *h3)
if *h3 {
conn.TLSTPHandler.MaxUniStreams = 3
}
if err != nil {
panic(err)
}
if *h3 {
conn.TLSTPHandler.MaxUniStreams = 3
}

pcap, err := m.StartPcapCapture(conn, *netInterface)
if err != nil {
Expand Down
22 changes: 10 additions & 12 deletions common.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,23 @@ import (
. "github.com/QUIC-Tracker/quic-tracker/lib"
_ "github.com/mpiraux/ls-qpack-go"
"github.com/mpiraux/pigotls"
"io"
"math"
"net"
"time"
)

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

const (
MinimumInitialLength = 1252
MinimumInitialLengthv6 = 1232
MaxUDPPayloadSize = 65507
MaximumVersion = 0xff000012
MinimumVersion = 0xff000011
MaximumVersion = 0xff000013
MinimumVersion = 0xff000013
)

// errors
Expand All @@ -65,7 +66,7 @@ const (
type PacketNumber uint64

func ReadPacketNumber (buffer *bytes.Reader) PacketNumber {
v, _ := ReadVarIntValue(buffer)
v, _, _ := ReadVarIntValue(buffer)
return PacketNumber(v)
}

Expand Down Expand Up @@ -124,15 +125,12 @@ type VarInt struct {
func NewVarInt(value uint64) VarInt {
return VarInt{value, VarIntLen(value)}
}
func ReadVarInt(buffer *bytes.Reader) (VarInt, error) {
v := VarInt{Length: buffer.Len()}
i, err := ReadVarIntValue(buffer)
func ReadVarInt(buffer io.ByteReader) (VarInt, error) {
i, l, err := ReadVarIntValue(buffer)
if err != nil {
return VarInt{}, err
}
v.Length -= buffer.Len()
v.Value = i
return v, nil
return VarInt{Value: i, Length: l}, nil
}

func (v VarInt) Encode() []byte {
Expand Down
8 changes: 1 addition & 7 deletions connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,13 +215,7 @@ func (c *Connection) GetAckFrame(space PNSpace) *AckFrame { // Returns an ack fr
return frame
}
func (c *Connection) TransitionTo(version uint32, ALPN string) {
var prevVersion uint32
if c.Version == 0 {
prevVersion = QuicVersion
} else {
prevVersion = c.Version
}
c.TLSTPHandler = NewTLSTransportParameterHandler(version, prevVersion)
c.TLSTPHandler = NewTLSTransportParameterHandler()
c.Version = version
c.ALPN = ALPN
c.Tls = pigotls.NewConnection(c.ServerName, c.ALPN, c.ResumptionTicket)
Expand Down
Loading

0 comments on commit 728f1a0

Please sign in to comment.